我对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 failedn");
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("Hellon");
printf(" SIZE OF ccc : %in", (int) sizeof(pdrd_osc));
printf(" ADDRESS ccc : %pn", ccc);
printf(" ADDRESS (INT) ccc : %lun", address_int(ccc));
printf(" ADDRESS ccc.omodel : %lun", address_int( &(ccc->omodel)));
printf(" ADDRESS ccc.no : %lun", address_int( &( ccc->no)));
printf(" ADDRESS ccc.beps : %lun", address_int( &( ccc->beps)));
printf(" ADDRESS ccc.egap : %lun", address_int( &( ccc->egap)));
printf(" ADDRESS ccc.aaa : %lun", address_int( &(ccc->aaa)));
printf(" ADDRESS ccc.aaa[0] : %lun", address_int( &(ccc->aaa[0])));
printf(" ADDRESS ccc.aaa[maxcol] : %lun", address_int( &(ccc->aaa[MAXCOL])));
printf(" ADDRESS ccc.ggg : %lun", address_int(&( ccc->ggg)));
printf(" ADDRESS ccc.ooo : %lun", address_int(&( ccc->ooo)));
printf(" ADDRESS ccc.ddd : %lun", 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
因此函数ini_drdosc
中的第一个malloc
在内存中保留了8个字节,这很好。然而,由该malloc
为变量omodel,no,beps
和egap
保留的地址空间被(固定大小阵列)aaa
的下一个malloc
覆盖,如aaa[0]
和aaa[maxcol]
的地址的打印输出所示。为什么?如何使编译器保护变量omodel,no,beps
和egap
以避免segfault等。?
我真的完全被困在这里了,如果我能得到任何帮助,我将不胜感激。提前感谢您的帮助!
您采用的是指针类型的大小,而不是结构本身。根据64/32位系统,这将分别为8字节和4字节。
ccc=malloc(sizeof(drd_osc_type)));
应该分配正确的大小。