我有一个关于为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个字节。我也不太明白这一点,因为长度只是一个整数,对我而言,这个错误听起来像是我想为它分配内存...
答案 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));
显然是错误的,因为类型Ablock
是struct ablock_ *
,即指针。你只是分配指针的大小,而不是指向的对象的大小。
你应该总是这样写:
agroup_main = malloc(sizeof *agroup_main);
在正确的类型上使用sizeof
,接收返回值的指针指向的类型。
我还强烈推荐反对 typedef
这样的指针,因为它增加了混乱。指针在C中很重要,隐藏它们通常会使事情更难理解和遵循,从而增加了出错的风险。问题“这是一个对象,还是一个指向对象的指针?”是非常重要的,你必须能够一直快速准确地回答它。