为什么在使用“引号”创建字符*时不需要释放内存

时间:2012-10-11 14:33:27

标签: c pointers char

我在测试一些代码时遇到了一个可怕的错误。我发现它是由调用free(p_current_item->s)引起的,其中p_current_item是链表中的节点,s是它包含的char *。我通过调用方法addItem(node,char *)来创建节点,该方法只是将元素添加到列表中:p_head=addItem(p_head,"this gets added"); 困扰我的是:

1)为什么我需要释放元素中包含的字符串。我知道当s被声明为char* s = snprintf(s,(size_t),30,"this gets added");时(这是在我的类示例中完成的方式)是必要的,但为什么这是必要的 - 是否可以将属性包含在结构中(在本例中为linkedList)在释放struct本身时释放?

2)当我试图释放显式声明的s的值时发生了什么

3)我是否需要以其他方式释放s的价值?

谢谢: - )

4 个答案:

答案 0 :(得分:4)

您只能free使用malloc系列电话分配的内存。

用双引号封装的字符串是编译时常量。它们与指令文本一起导入到运行时程序中。因此,那些尚未动态分配。

同样snprintf返回生成的字符串的长度,而不是指向它的指针。正确的用法是:

size_t length = snprintf(s,(size_t)30,"this gets added");

1)如果使用smalloc或该家庭的其他电话分配,则您只需要免费calloc。例如char* s = malloc(1024);

2)free("constant string");最多会导致分段违规,因为您尝试释放尚未由malloc系列调用分配的内存。通常这是未定义的行为。

3)你不需要释放常量字符串,它们是你文本的一部分,即使你想这样做也不能被释放。

答案 1 :(得分:0)

当您在代码中声明s时,它不会在堆中分配。只有当您需要释放使用free()malloc在堆中动态分配的内存时,才会调用calloc - 这在您的代码中并非如此。

答案 2 :(得分:0)

"this gets added"这样的文字字符串在可执行文件中分配了固定内存地址,就像全局和static变量一样。你不需要也不能解除它们。

如果你的情况是清理功能不知道是否需要调用free(),有时可能需要调用,最好的解决方案是制作基于堆的所有内容副本并始终致电free()。方便的是,您可以使用strdup()

执行此操作
p_head=addItem(p_head, strdup("this gets added"));

答案 3 :(得分:0)

  

1)为什么我需要释放元素中包含的字符串。一世   知道s被声明为char * s =时是必要的   snprintf(s,(size_t),30,“这被添加”); (这是怎么做的   在我的班级例子中)但为什么这是必要的 - 是否有可能   结构中包含的属性(在本例中为linkedList)   在释放struct本身时释放?

您需要释放已分配的内存

char *s = snprintf(s, ...)

做错了。你需要:

char *s = NULL;   // Declare memory -- and initialize it to NULL just to be safe.
                  // This way, using unallocated memory will be easily spotted.

s = malloc(30);   // Allocate the memory
if (NULL == s)    // Check that it has been allocated.
{
    abort();
}
// Use the memory: sprintf into s
snprintf(s, "My name is %s", 30, "John");

// Use the result
printf("%s\n", s);

free(s);    // Free the memory
s = NULL;   // If you're really paranoid, NULL out its pointer.
            // This way, also using no-longer-allocated memory will be spotted.

你也可能遇到 valgrind ,发现他是一个不灵活但又很有价值的朋友。

  

2)当我试图释放s的值时发生了什么   明确声明

没什么好的:-)。内存分配器发现了一个错误,并迅速崩溃了你的程序以避免更糟糕的情况发生。

  

3)我是否需要以其他方式释放s的价值?

如果你已经分配了它,是的。见上文。