所以我的理解是这两个代码块是有效的并且做同样的事情。
1。)
char *ptr = malloc(5);
ptr = "hi";
2)。
char *ptr = "hi";
我想知道两者之间的区别,比如一方面有什么优势。
答案 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
在第二种情况下,没有内存泄漏,并且您正在指向指向字符串文字的指针,因此它的值无法修改,因为它将存储在只读数据段中。