使用malloc后程序正常打印但栈转储,free语句引发错误求原因
问题分析:malloc内存与字符串字面量的冲突导致free报错
你的程序代码:
#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { char * pt[3]; size_t size = sizeof(char); pt[0] = (char *) malloc(60 * size); pt[1] = (char *) malloc(60 * size); pt[2] = (char *) malloc(60 * size); pt[0] = "Earth"; puts(pt[0]); puts("==================================="); pt[1] = "University"; puts(pt[1]); puts("==================================="); pt[2] = "Things are very interesting!"; puts(pt[2]); puts("==================================="); for (int i = 0; i < 3; i++) { free(pt[i]); } return 0; }
错误原因
你遇到的free报错核心问题是指针指向被非法篡改:
- 你先用
malloc在堆上分配了三块内存,把对应的堆地址存在pt数组的三个元素里。 - 但之后执行
pt[0] = "Earth";这类语句时,你并没有把字符串内容拷贝到之前分配的堆内存里,而是直接把pt[0]的指向改成了只读数据段中的字符串字面量地址。这会导致两个问题:- 原本
malloc分配的堆内存地址被丢失,造成内存泄漏; pt数组里现在存的是字符串字面量的地址,而free函数只能用于释放堆上分配的内存,对只读数据区的地址执行free属于非法内存操作,直接触发了你看到的栈转储错误。
- 原本
修复方案
如果你想把字符串内容存入之前malloc分配的堆内存,需要用字符串拷贝函数(比如strncpy,比strcpy更安全):
// 替换pt[0] = "Earth";这类语句 strncpy(pt[0], "Earth", 59); // 只拷贝59个字符,留一个位置给字符串结束符'\0' pt[0][59] = '\0'; // 手动添加结束符,避免读取越界
或者可以使用strdup函数(该函数会自动分配足够的内存并拷贝字符串,注意最后同样需要free):
// 先释放之前malloc的内存,再用strdup重新分配并拷贝 free(pt[0]); pt[0] = strdup("Earth");
内容的提问来源于stack exchange,提问作者user9026
相关产品推荐
相关产品推荐

