为struct分配内存

时间:2014-04-30 05:16:57

标签: c struct

我有一个关于为c中的结构分配内存的一个相当简单的问题,我尝试在线查看,但我找不到任何东西。结构定义为:

typedef struct cblock_ {
....
} cblock, *Cblock;

分配内存时,我已尝试过

Cblock new_block = malloc(sizeof(struct cblock_));

但是,我不断收到内存损坏错误。我已经尝试将sizeof的参数更改为不同的东西,但是所有内容都会出现相同的内存损坏错误。我做错了什么?

**** **** EDIT

因此在运行valgrind后,我得到了相当多的"无效的写入大小4"或"无效读取大小4和#34;在我的代码中。

发布所有内容可能太多了,但是这里有一个地方,其中valgrinds给了我一个"无效的4号和34号写入;

static Ablock agroup_main;    

typedef struct ablock_ {
    int length;
    int num;
    ...
} ablock, *Ablock;

void init_groups() {
    agroup_main = malloc(sizeof(Ablock));

    agroup_main->length = DEFAULT_GROUP_LENGTH;
    agroup_main->num = DEFAULT_GROUP_NUM;

}

Valgrind在线路设置长度上说它是4号的无效写入,并且地址是大小为4分配的块后的0字节。对于num,它是相同的,除了地址是大小为4的块之后的4个字节。我也不太明白这一点,因为长度只是一个整数,对我而言,这个错误听起来像是我想为它分配内存...

2 个答案:

答案 0 :(得分:5)

内存损坏可能是因为早期不正确malloc(例如,尺寸太小),过早free或真正的缓冲区溢出(或未初始化的指针取消引用) )。

使用内存泄漏检测器。在Linux上,尝试valgrind

malloc Cblock看起来没问题。这个bug可能在其他地方。不要忘记编译所有警告和调试信息(例如gcc -Wall -g)。还可以使用调试器(例如gdb)。您可能希望禁用ASLR以简化调试(并且具有更多可重现的运行)。

您应该测试malloc

的结果
cblock* new_block = malloc(sizeof(struct cblock_));
if (!new_block) { 
    perror("malloc cblock"); 
    exit(EXIT_FAILURE); 
}

我认为你应该清楚地标记代码中的所有指针(所以我更喜欢cblock*而不是Cblock,我觉得这很困惑,至少应该将其命名为CblockPtr

顺便说一下,你被这种混乱所困扰:

    agroup_main = malloc(sizeof(Ablock));  // WRONG!

是不正确的,因为Ablock是指针类型(在Linux / PC上,所有指针都具有相同的大小,在x86-64上为8个字节)。你的意思是

    agroup_main = malloc(sizeof(ablock));
    if (!agroup_main) 
       { perror("malloc ablock"); exit (EXIT_FAILURE); };

你真的应该放弃以隐藏指针的方式命名指针类型的坏习惯(并且使用类似于指向数据的名称)。

答案 1 :(得分:3)

此:

agroup_main = malloc(sizeof(Ablock));

显然是错误的,因为类型Ablockstruct ablock_ *,即指针。你只是分配指针的大小,而不是指向的对象的大小。

你应该总是这样写:

agroup_main = malloc(sizeof *agroup_main);

在正确的类型上使用sizeof,接收返回值的指针指向的类型。

我还强烈推荐反对 typedef这样的指针,因为它增加了混乱。指针在C中很重要,隐藏它们通常会使事情更难理解和遵循,从而增加了出错的风险。问题“这是一个对象,还是一个指向对象的指针?”是非常重要的,你必须能够一直快速准确地回答它。