C语言释放结构体char*成员时程序崩溃,求正确释放方法
问题根源与解决方案
崩溃原因
程序崩溃的核心问题是:你最终让wordContainer.word指向了字符串常量,而非malloc分配的堆内存。free只能释放堆上的动态分配内存,释放静态存储区的字符串常量会触发未定义行为,直接导致程序崩溃。
看你代码里的错误逻辑:
listIN[i].word = (char *)malloc(50*sizeof(char)); // 分配堆内存 listIN[i].word = "empty"; // 指针被覆盖,指向字符串常量"empty",堆内存地址丢失(泄漏) listIN[i].word = "cow"; // 再次覆盖指针,指向另一个字符串常量"cow"
你分配的堆内存根本没被使用,最后word指向的是程序静态存储区的常量,这部分内存不属于堆,不能用free释放。
正确的内存处理方式
方式1:动态分配内存存储字符串(支持修改/释放)
如果需要后续修改字符串内容,或者必须通过free释放内存,要把字符串内容复制到堆内存中,不能直接赋值指针:
wordContainer *SetupWordList(int *size, int *lastInit, wordContainer *listIN, bool reallocate) { if(!reallocate) { // C标准中无需强制转换malloc返回值 listIN = malloc((*size) * sizeof(wordContainer)); if (listIN == NULL) { fprintf(stderr, "Could not allocate enough memory.\n"); exit(EXIT_FAILURE); } } else { // realloc失败时不会释放原指针,用临时变量接收避免内存泄漏 wordContainer *temp = realloc(listIN, (*size) * sizeof(wordContainer)); if (temp == NULL) { fprintf(stderr, "Realloc failed.\n"); exit(EXIT_FAILURE); } listIN = temp; } for (int i = (*lastInit); i < (*size); i++) { // 分配内存后,用strcpy复制字符串内容到堆内存 listIN[i].word = malloc(50 * sizeof(char)); if (listIN[i].word == NULL) { fprintf(stderr, "Failed to allocate memory for word.\n"); exit(EXIT_FAILURE); } strcpy(listIN[i].word, "cow"); // 将"cow"复制到堆内存 listIN[i].amount = 0; } *lastInit = *size; *size *= 2; return listIN; }
此时你可以安全取消main中free(listWords[i].word)的注释,程序不会崩溃。
方式2:直接使用字符串常量(无需释放)
如果不需要修改字符串内容,直接用字符串常量即可,但绝对不能调用free:
for (int i = (*lastInit); i < (*size); i++) { listIN[i].word = "cow"; // 直接指向静态存储区的常量 listIN[i].amount = 0; }
这种情况下main中的free(listWords[i].word)必须保持注释状态。
内容的提问来源于stack exchange,提问作者RobBobert
相关产品推荐
相关产品推荐

