在为数组分配的内存上发出free()问题

时间:2014-08-21 21:09:11

标签: c dynamic-arrays

我正在研究如何正确处理C中的指针,数组等。我在为它们分配内存然后释放内存时有点困惑。以下是我一起拍的一些测试代码:

char *test[150000];
char **ptr;

for(int i = 0; i < 150000; i++)
{
    test[i] = malloc(15*sizeof(char));
    test[i] = "This is a test";
    printf("test[%i] = %s located at %p\n",i,test[i],&test[i]);
}

for(int i=0; i < 150000; i++)
{
    printf("Trying to free memory from %p\n",&test[i]);
    ptr = &test[i];
    free(ptr);
    printf("Array item %i has been freed...",i);
}

输出结果如下:

[... Truncated]

test[149997] = This is a test located at 0x7fff581fbcc8
test[149998] = This is a test located at 0x7fff581fbcd0
test[149999] = This is a test located at 0x7fff581fbcd8
Trying to free memory from 0x7fff580d6d60
test2(17599,0x7fff7776f310) malloc: *** error for object 0x7fff580d6d60: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
sh-3.2# 

看来,当我尝试释放分配的指针时,我收到一个错误......任何有关我搞砸的想法/指示都会非常感激。

2 个答案:

答案 0 :(得分:2)

test[i] = malloc(15*sizeof(char));

这是可以的,除了(a)它可以写成test[i] = malloc(15);,(b)你不检查malloc是否成功。

test[i] = "This is a test";

将字符串"This is a test"的内容复制到刚刚分配的内存中。相反,它是一个指针赋值,导致test[i]指向字符串文字的内存。它会产生内存泄漏,因为您不再有指向使用malloc分配的内存的指针。您可能想要使用strcpy

...
ptr = &test[i];
free(ptr);

这里你free分配给字符串文字的内存,而不是你分配的内存。

更正:这不是它的作用。它试图free指针对象本身,这甚至没有意义。 (顺便提一下,free的参数不一定是对象名; free(&test[i])同样合法 - 同样不正确。)

假设你修复了分配问题,你想要的只是:

free(test[i]);

答案 1 :(得分:0)

char *test[150000];
char **ptr;

for(int i = 0; i < 150000; i++)
{
test[i] = malloc(15*sizeof(char));
/*test[i] = "This is a test";*/ // Fix1
printf("test[%i] = %s located at %p\n",i,test[i],&test[i]);
}

for(int i=0; i < 150000; i++)
{
printf("Trying to free memory from %p\n",&test[i]);
/*ptr = &test[i];*/ //Fix2
free(test[i]); //Fix3
printf("Array item %i has been freed...",i);
}

Fix1: 堆内存已分配并存储到 test [i] 中。所以 test [i] 具有有效地址。但是再次使用此语句覆盖 test [i] 地址test[i] = "This is a test";如果要将字符串复制到test [i]中,请使用strcpy。 假设您想要像这样分配test[i] = "This is a test";,请不要在此之前分配动态内存。也不需要自由。

FIX2&安培; Fix3: 分配的地址存储在test[i]而不是&amp; test [i]中。所以只需释放test[i]中的地址即可。也不需要使用中间变量。如果需要使用中间变量,则更喜欢使用char *ptr