C语言给结构体成员赋值后释放结构体触发段错误问题求助
问题根因
你触发段错误的核心原因是结构体内存分配时计算大小错误,导致堆内存越界写入,S->len = length的赋值操作破坏了堆的元数据,后续操作内存时触发崩溃,二者是直接关联的。
具体错误分析
1. 结构体分配大小错误(直接导致崩溃)
你的代码中String是struct string*的别名,属于指针类型:
S = (String) malloc (sizeof (String));
这里sizeof(String)计算的是指针的大小(32位系统为4字节,64位系统为8字节),而你实际需要分配的是整个struct string结构体的内存。struct string包含两个成员:char* str(指针,64位8字节) + int len(4字节,内存对齐后总大小为16字节),你只申请了8字节内存,仅够存储第一个成员str。
当你执行S->len = length时,是向超出你申请范围的内存地址写入数据,属于堆越界写,直接破坏了堆内存的管理元数据,后续执行free、*Sp = NULL等操作时就会触发段错误。
你删除S->len = length后没有崩溃,只是因为你没有触发越界写,堆元数据没有被破坏,属于侥幸未触发问题,代码本身的内存越界bug依然存在。
2. 字符串分配类型错误(潜在bug)
你分配字符串内存的代码也有问题:
S->str = (char*) malloc (sizeof (char*) * length + 1);
这里错误使用了sizeof(char*)(指针大小),而存储字符需要的是char类型的大小,标准规定sizeof(char)恒为1,所以正确写法是malloc(length + 1)即可,你的写法会导致分配的内存是实际需要的N倍(64位下是8倍),存在内存浪费和后续越界风险。
修正后的代码
String new_string (int length) { String S; // 分配整个结构体的内存,而非指针大小 S = (String) malloc(sizeof(struct string)); if (S == NULL) return NULL; // 分配字符串内存,长度为length+1 S->str = (char*) malloc(length + 1); if (S->str == NULL) { free(S); // 分配失败先释放已申请的结构体内存,避免泄漏 return NULL; } S->str[length] = '\0'; S->len = length; return S; }
内容的提问来源于stack exchange,提问作者ridthyself
相关产品推荐
相关产品推荐

