结构中数组的内存分配问题

时间:2016-08-01 09:52:21

标签: c arrays struct malloc

我对c比较陌生并且有一个棘手的问题, 我已将其跟踪到内存分配问题(请参阅下面的代码),但不明白为什么编译器正在执行此操作并且想知道如何正确执行此操作。我在gcc(GCC)4.5.1 20100924(Red Hat 4.5.1-4)上运行它。 下面的代码应该单独编译,至少在我的系统上编译。

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <time.h>


  #define MAXCOL       100   
  typedef enum {
    DL,                
    DLIMEPS            
  } omodel_type;       

  typedef  double *   pcn_type;  
  struct drd_osc_type{
    pcn_type aaa;      
    pcn_type ggg;      
    pcn_type ooo;      
    pcn_type ddd;      
    omodel_type omodel;
    double beps;       
    double egap;       
    int no;            
  };
  typedef struct drd_osc_type * pdrd_osc;


//=====================================================================
unsigned long int  address_int(void * ccc){
  char *s=malloc(100);
  sprintf(s,"%p", ccc);
  int x;
  sscanf(s,"%x",&x);
  return x;
}

//=====================================================================

pdrd_osc   ini_drdosc(){
  pdrd_osc  ccc;

  if ( (ccc=malloc(sizeof(pdrd_osc)))==NULL){
       perror("malloc 3");
    printf("ini_drdosc :malloc failed\n");
       return NULL;
   }
  ccc->omodel=DL;
  ccc->no=0;
  ccc->beps=1;
  ccc->egap=0;
  ccc->aaa=malloc(100*sizeof(double));
  ccc->ggg=malloc(100*sizeof(double));
  ccc->ooo=malloc(100*sizeof(double));
  ccc->ddd=malloc(100*sizeof(double));
  int i;
  for (i=0;i<MAXCOL;i++)ccc->aaa[i]=0.0;
  for (i=0;i<MAXCOL;i++)ccc->ggg[i]=0.0;
  for (i=0;i<MAXCOL;i++)ccc->ooo[i]=0.0;
  for (i=0;i<MAXCOL;i++)ccc->ddd[i]=0.0;
  //printf("Hello\n");
  printf(" SIZE OF ccc             : %i\n", (int) sizeof(pdrd_osc)); 
  printf(" ADDRESS ccc             : %p\n",  ccc); 
  printf(" ADDRESS (INT) ccc       : %lu\n",  address_int(ccc)); 
  printf(" ADDRESS ccc.omodel      : %lu\n", address_int( &(ccc->omodel))); 
  printf(" ADDRESS ccc.no          : %lu\n",     address_int( &( ccc->no))); 
  printf(" ADDRESS ccc.beps        : %lu\n",   address_int( &( ccc->beps))); 
  printf(" ADDRESS ccc.egap        : %lu\n",   address_int( &( ccc->egap))); 
  printf(" ADDRESS ccc.aaa         : %lu\n",    address_int( &(ccc->aaa))); 
  printf(" ADDRESS ccc.aaa[0]      : %lu\n",    address_int( &(ccc->aaa[0]))); 
  printf(" ADDRESS ccc.aaa[maxcol] : %lu\n",    address_int( &(ccc->aaa[MAXCOL]))); 
  printf(" ADDRESS ccc.ggg         : %lu\n",    address_int(&( ccc->ggg))); 
  printf(" ADDRESS ccc.ooo         : %lu\n",    address_int(&( ccc->ooo))); 
  printf(" ADDRESS ccc.ddd         : %lu\n",    address_int(&( ccc->ddd))); 
  return ccc;
}
int main(int argc, char* argv[]) {
pdrd_osc drdosc;drdosc=(pdrd_osc) ini_drdosc();
  return 0;
}

当我编译并运行它时,我得到以下结果:

 SIZE OF ccc             : 8
 ADDRESS ccc             : 0x1086010
 ADDRESS (INT) ccc       : 17326096
 ADDRESS ccc.omodel      : 17326128
 ADDRESS ccc.no          : 17326152
 ADDRESS ccc.beps        : 17326136
 ADDRESS ccc.egap        : 17326144
 ADDRESS ccc.aaa         : 17326096
 ADDRESS ccc.aaa[0]      : 17326128
 ADDRESS ccc.aaa[maxcol] : 17326928
 ADDRESS ccc.ggg         : 17326104
 ADDRESS ccc.ooo         : 17326112
 ADDRESS ccc.ddd         : 17326120

因此函数malloc中的第一个ini_drdosc在内存中保留8个字节,这很好。但是,此malloc为变量omodel,no,bepsegap保留的地址空间将被(固定大小数组)malloc的下一个aaa覆盖,正如aaa[0]aaa[maxcol]地址的打印输出所示。为什么?如何使编译器保护变量omodel,no,bepsegap以避免段错误等?

我真的完全被困在这里,并希望得到任何帮助。在此先感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

您正在使用指针类型的大小而不是结构本身。根据64 / 32bit系统,这将分别为8和4字节。

ccc=malloc(sizeof(drd_osc_type)));

应分配正确的尺寸。