将字符串指针首先分配给已分配的内存并直接分配给字符串文字有什么区别?

时间:2014-09-01 13:36:10

标签: c

所以我的理解是这两个代码块是有效的并且做同样的事情。

1。)

char *ptr = malloc(5);
ptr = "hi";

2)。

char *ptr = "hi";

我想知道两者之间的区别,比如一方面有什么优势。

4 个答案:

答案 0 :(得分:4)

前者是一个错误,该代码永远不应该被写入。

它用字符串文字的地址覆盖malloc()返回的指针,删除原始指针并泄漏内存。

您必须使用strcpy()或其他一些内存复制方法来使用字符串初始化新分配的堆内存。

第二个只是将字符串文字的(运行时常量)地址分配给指针ptr,不会在任何地方复制字符。

答案 1 :(得分:3)

第一位是可能的内存泄漏,第二位依赖于正在使用的隐式const存储类,并将不可变字符串的内存地址分配给指针。
基本上是:

char *ptr = malloc(5);//allocates 5 * sizeof *ptr
//then assigns the address where this block starts to ptr
//this:
ptr = "hi";//assigns position of 'h','i', '\0' in read-only mem to ptr

现在,您分配的ptr指向的地址仍然已分配。区别在于你不再使用“handle”,因为ptr的值已更改。没有指针指向您使用malloc分配的动态内存,因此管理内存变得相当棘手......您可能无法free它,并且调用{{1} } free现在将导致未定义的行为 如果你写:

ptr

然后你真的在写:

char *ptr = "hi";

这意味着您无法更改const char *ptr = "hi"; 指向的字符串:

ptr

替代方案是:

ptr[0] = 'H';//IMBOSSIBRU

上面两个片段之间的区别在于第一个创建了一个堆栈数组,第二个在堆上分配了一块内存。堆栈内存更容易管理,更快,几乎在所有方面都更好,除了它不那么丰富,并且不能真正用作返回值......

答案 2 :(得分:0)

每个进程都有一个字符串文字池。无论何时在代码中创建字符串文字,文字都会保存在池中,并返回字符串的地址(即指向池中某处的地址)。因此,您在第一个选项中创建了内存泄漏,因为您正在覆盖使用malloc收到的地址。

答案 3 :(得分:0)

在第一种情况下

char *ptr = malloc(5);
ptr = "hi";

存在内存泄漏,之后您将ptr指向字符串文字“hi”,这确实需要堆中的任何内存(这就是内存泄漏的原因)。

但是如果你正在分配内存而你正在使用

strcpy (ptr, "hi");

然后如果你希望你可以修改它

strcpy (ptr, "hello")

有一个条件是你之前分配了足够的内存。

但是在你的情况下,你正在用字符串文字指定一个指针 ptr ,在这里你将无法修改它

ptr = "hello"            // not valid. This will give a segmentation fault error

在第二种情况下,没有内存泄漏,并且您正在指向指向字符串文字的指针,因此它的值无法修改,因为它将存储在只读数据段中。