C语言malloc内存后free时出错

COSE 发布于 2013/11/04 13:06
阅读 2K+
收藏 1
C语言malloc内存后free时出错
int main()
{
	char a[256] = "Richard Matthew Stallman";

	size_t i;
	char **arr;
	arr = (char **)malloc(sizeof(char *) * 10);
	for (i = 0; i < 10; ++i) {
        arr[i] = (char *)malloc(sizeof(char) * 256);
    }
	
	char *tmp;
	if (!(tmp = (char *)malloc((strlen(a) + 1) * sizeof(char)))) {
		return -1;
	}
	
	strcpy(tmp, a);
	arr[0] = tmp;
	for (i = 1; *tmp; ++tmp) {
		if (*tmp == ' ') {
			*tmp = '\0';
			arr[i++] = tmp + 1;
		}
	}
	
	free(tmp);  /* 执行这里时出错 */
	
	for (i = 0; i < 10; ++i) {
		free(arr[i]);
	}
	free(arr);
	return 0;
}
gdb信息如下:
Program received signal SIGSEGV, Segmentation fault.
0x00b719dc in free () from /lib/libc.so.6
加载中
0
lingxi27
lingxi27
free()  frees  the memory space pointed to by ptr, which must have been
       returned by a previous call to malloc() , calloc() or realloc().  Other‐
       wise,  or if free(ptr) has already been called before, undefined behav‐
       ior occurs.  If ptr is NULL, no operation is performed.

你纠结一个未定义行为,没什么意义

简单来说

++tmp;


free(tmp);
这种用法是错误的

0
花想容

++tmp

tmp指针已经变了,不是原来malloc的tmp,free就失败

0
COSE
COSE

引用来自“花想容”的答案

++tmp

tmp指针已经变了,不是原来malloc的tmp,free就失败

char *tmp = malloc(sizeof(char) * 24);
  ++tmp;
  free(tmp);
测试上面代码可以通过啊
花想容
char *tmp = malloc(sizeof(char) * 24); 2 ++tmp; 3 free(tmp); 只能说凑巧没崩溃
花想容
那是凑巧 for (i = 1; *tmp; ++tmp) tmp指针改好几次了
0
COSE
COSE

引用来自“lingxi27”的答案

free()  frees  the memory space pointed to by ptr, which must have been
       returned by a previous call to malloc() , calloc() or realloc().  Other‐
       wise,  or if free(ptr) has already been called before, undefined behav‐
       ior occurs.  If ptr is NULL, no operation is performed.

你纠结一个未定义行为,没什么意义

简单来说

++tmp;


free(tmp);
这种用法是错误的

int str_split(char *arr[], char *str, char delim) {
	size_t i;

	arr[0] = str;
	for (i = 1; *str; ++str) {
		if (*str == delim) {
			*str = '\0';
			arr[i++] = str + 1;
		}
	}
	
	return i;
}

int main()
{
	char *a = "While mobile technology will no doubt bring productivity gains, it also stands to tax organizations on how and where data can be captured and used. How will meetings be different if anyone present can record every image? What is the acceptable use of data collected and stored on devices carried by individuals? Can information captured on wearables be used as evidence against an employee? Which data is a corporate asset and needs to be captured and governed? These are the issues that will be hammered out over the coming years as the workforce adapts to data constantly on the move";

	size_t i;
	char **arr;
	arr = (char **)malloc(sizeof(char *) * 500);
	for (i = 0; i < 500; ++i) {
        arr[i] = (char *)malloc(sizeof(char) * 100);
    }
	
	size_t n = str_split(arr, a, ' ');
	for (i = 0; i < n; ++i) {
		printf("%s ", arr[i]);
	}
	
	printf("\n");
	
	for (i = 0; i < 10; ++i) {
		free(arr[i]);
	}
	free(arr);
	
	return 0;
}
请教另外一个问题,我修改了函数,但是运行上面的程序时依然出错,检查后将字符串a的声明由char *a = “..." 修改为char a[] = "..."就可以成功执行,请教下原因。
lingxi27
lingxi27
*a = "..."又是另一个“错误用法” 此时a指向的字符串位于代码段,是只读的 试图修改这段内容当然会出错
0
ad_long
ad_long
空格分割字符串,用strtok库函数吧


0
昏鸦
昏鸦
for  (i = 1; *tmp; ++tmp) {   这个已经改变了tmp指向的值了
0
cytzrs
cytzrs

malloc分配的是一个整块的未初始化的空间,不能用下标进行操作。可以用calloc
  

 char **arr;
    arr = (char **)calloc(500,sizeof(char *) );
    for (i = 0; i < 500; ++i) {
        arr[i] = (char *)calloc(100,sizeof(char) );
    } 

0
晓风拂柳
晓风拂柳
arr[0]已经分配过,又把tmp赋值给它,后面又 arr[i++] = tmp + 1;  内存泄漏如此严重,不敢直视,代码写成这样糟糕也是一种境界
返回顶部
顶部