在C语言中释放字符串

13

如果我写下以下代码:

char *a=malloc(sizeof(char)*4);
a="abc";
char *b="abc";

我需要释放这个内存吗,还是由我的系统自动完成了?


另外一点评论是,我认为你不需要sizeof(char),因为在我所见过的所有实现中,它始终为1字节。因此,malloc(4);就足够了。 - Lefteris
2
@Lefteris 实际上,上述实现是不错的。虽然大多数系统使用一字节字符,但上述实现清楚地表明了正在分配什么,如果代码更改为使用通常为两个字节的unichars,则更容易进行更改。 - ThomasW
@ThomasW,恐怕我不确定什么是unichar,但我认为它与unicode有关。快速的谷歌搜索表明这是另一种语言:objective-c。但是任何Unicode字符通常都不被称为char。以宽字符wchar_t为例。可能是错的,但这是我处理过的实现中迄今为止看到的情况。 - Lefteris
是的,unichar 是 Unicode 字符,但这个概念并不特定于 Objective-C。通常来说,假设数据结构的大小并不是一个好主意。 - ThomasW
6个回答

18

在您的情况下,您将无法释放动态分配的内存,因为您失去了对它的引用。

尝试一下这个:

#include <stdio.h>
#include <stdlib.h>

int main()
{
  char *a=(char*)malloc(sizeof(char)*4);
  printf("Before: %p\n",a);
  a = "abc";
  printf("After: %p\n",a);
  free(a);
  char *b = "abc";

  return 0;
}

你将获得

Before: 0x100100080
After: 0x100000f50

你会发现这两个指针是不同的。这是因为字符串字面量"abc"被放置在二进制文件的数据部分中,当你执行

a = "abc"

你正在将指针 a 改为指向常量字符串 "abc",并且你失去了先前分配的内存。现在调用 free 函数释放 a 不再正确,因为它不再指向一个有效的动态分配的地址。如果要保留指针并能够释放它,你应该使用复制字符串的方式。

strncpy(a, "abc", 4)
这将有效地将字符从字面量复制到动态分配的方法中,保留原始指针。

4
strcpy 是许多缓冲区溢出漏洞的根源。请改用 strncpy。 - rampion
你说得对,我只是考虑了这个特定的情况,让我来编辑一下。 - Jack
@rampion 只是出于好奇,你为什么这样说呢?因为 strcpy 复制 strlen(source) 个字节,可能没有针对目标缓冲区大小进行检查吗?还是我理解有误? - Lefteris
1
@Lefteris 这个问题根本没有被检查, strcpy 函数会复制 strlen(source) 个字符而不考虑目标字符串的大小。如果源字符串长度大于目标字符串长度,则它将写入越界。 - Jack
1
@Andna 当然,如果你使用 strncpy,你将不得不在代码末尾使用 free(a) 释放内存。 - Jack
@Jack 是的,这就是我想说的。我所说的“被检查”是指由你(程序员)来检查。Strncpy需要额外的变量,这让你想,“嘿,我得在这里检查一下,没有什么是自动的” :) - Lefteris

6
这里存在内存泄漏。当你设置a="abc"时,你并没有填充刚刚分配的内存,而是重新指定指针指向静态字符串"abc"。 b指向同样的静态字符串。
相反,你需要使用strncpy(a, "abc", 4),它将把"abc"的内容复制到你分配的内存中(a指向该内存)。
然后,当完成时,你需要释放掉它。

3

在C语言中,你不能以这种方式分配字符串。

a = "abc"

但是如果你使用 malloc,那么你必须像这样使用 free

free(a);

但是请注意,如果你在示例中使用free(a),你会得到一个错误。因为在malloc之后,你将指针a的值更改为静态字符串"abc";所以下一个free(a)尝试释放静态数据。这样就会导致错误。


3
简单回答是“是”或“否”,另外你的代码有缺陷。
详细回答:
char *a=malloc(sizeof(char)*4);

你需要释放你分配的内存。
a="abc";

这将把一个指向常量字符串的指针赋给你的char* a,这样做会失去在第一行分配的内存的指针,你永远不应该释放常量字符串。
使用strcpy(a,"abc");代替a="abc";将字符串移动到分配的内存中。

3
strcpy 是许多缓冲区溢出漏洞的根源。请改用 strncpy。 - rampion

0

是的,它会导致内存泄漏。系统无法处理这种情况。


-1

是的,你需要释放由malloc返回的内存。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接