【发布时间】:2016-05-08 14:04:13
【问题描述】:
我有下面的代码,当我遇到分段错误时我已经评论过,什么时候没有。
最初我遇到了分段错误,然后我发现我可能无法初始化我的 char 指针位置,例如 "abcd"。但我无法理解 - 为什么?
我以为testString = "abcd"; 会将a 放在第一个内存地址,b 放在第二个,依此类推...
根据我初始化内存位置的方式,尝试释放内存时发生分段错误。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char* testString = malloc(sizeof(char) * 5);
printf("Size of char is: %d\n", sizeof(char));
printf("Size of int is: %d\n", sizeof(int));
for(int i = 0; i < 5; i++)
{
printf("Pointer addresses are: %p\n", testString + i);
}
char* tempPtr = testString + 2;
printf("My temp pointer address = %p\n", tempPtr);
// This gives me segmentation fault ....
testString = "abcd";
// This will not give me segmentation fault ....
//int count = 65;
//for(int i = 0; i < 5; i++)
//{
// testString[i] = count + i;
//}
printf("Printing character...\n");
for(int i = 0; i < 5; i++)
{
printf("Characters are: %c\n", testString[i]);
}
printf("Freeing memory...\n");
free(testString);
//printf("Access after freeing >>%c<<\n", tempPtr[0]);
//free(testString);
}
基于@M.M.和@Jonathan 的评论我知道testString = "abcd"; 我的testString 将指向创建字符串“abcd”的内存位置,因为我没有对其进行malloc,所以我无法释放它。此外,由于我原来指向堆内存的指针(我使用 malloc 得到的)已经消失,所以这是对内存或内存的浪费。
那么,是不是说当我使用像printf("Printing character...\n");这样的printf语句时,这也是内存泄漏呢?那我该如何避免呢?循环并插入 char* 肯定是个坏主意。
【问题讨论】:
-
testString = "abcd"表示指针testString现在将指向包含"abcd"的内存位置。然后你尝试free那个位置,导致分段错误。 -
请注意,
testString = "abcd";会丢弃指向已分配内存的指针(内存泄漏)。也许你需要strcpy()。而且由于malloc()(或calloc()或realloc())没有返回字符串文字(指针值),所以你不能释放它。 -
@l3x 我不想使用一些内置函数,想实现最基本的方法。不过感谢您的评论。
-
发生内存泄漏是因为
testString包含指向已分配内存的唯一指针。当您分配testString = "abcd"时,您将一个新的、不同的指针值分配给testString。您不能再释放malloc()返回的指针,因为您不再有它的记录。字符串"abcd"存在于程序的内存空间中;这不是内存泄漏。导致泄漏的是指针覆盖。printf("…")操作不会泄漏内存。 -
字符串
"abcd"将存在于内存中的某处。它很可能在文本段中,因为字符串文字是只读的,但标准并没有要求任何关于段的内容。不会在malloc()管理的堆区;它也可能不会在堆栈上。它很可能在数据段或文本段中——现在,在文本段中,尽管从历史上看,它本来应该在数据段中。
标签: c segmentation-fault