我对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,beps
和egap
保留的地址空间将被(固定大小数组)malloc
的下一个aaa
覆盖,正如aaa[0]
和aaa[maxcol]
地址的打印输出所示。为什么?如何使编译器保护变量omodel,no,beps
和egap
以避免段错误等?
我真的完全被困在这里,并希望得到任何帮助。在此先感谢您的帮助!
答案 0 :(得分:2)
您正在使用指针类型的大小而不是结构本身。根据64 / 32bit系统,这将分别为8和4字节。
ccc=malloc(sizeof(drd_osc_type)));
应分配正确的尺寸。