我有简单的代码,
#include "stdafx.h"
#include <malloc.h>
int main()
{
char *p = (char*) malloc(10);
p = "Hello";
free(p);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
此代码在终止时给出运行时异常.以下是错误最快的,
调试断言失败!
程序:...\my documents\visual studio 2010\Projects\samC\Debug\samC.exe文件:f:\ dd\vctools\crt_bld\self_x86\crt\src\dbgheap.c行:1322
表达式:_CrtIsValidHeapPointer(pUserData)
有关程序如何导致断言失败的信息,请参阅有关断言的Visual C++文档.
p = "Hello";使得p指向一个字符串字面量并丢弃先前分配的值.你不能free是字符串文字.你无法修改它.
如果你想p保留该字符串,只需使用
char* p = "Hello";
Run Code Online (Sandbox Code Playgroud)
要么
char p[] = "Hello";
Run Code Online (Sandbox Code Playgroud)
如果你打算修改它.
两者都不需要free.
这就是将 malloc 分配的内存中的字符串写入 char 指针的方式。
strcpy(p, "Hello");
Run Code Online (Sandbox Code Playgroud)
更换线路
p = "Hello";
Run Code Online (Sandbox Code Playgroud)
与strcpy您的程序将正常工作。
你还需要
#include <string.h>
Run Code Online (Sandbox Code Playgroud)
malloc返回一个指向已分配内存的指针。假设地址是 95000(只是我拉出来的一个随机数)。
所以在 malloc 之后 - p 将保存地址95000
p 包含的95000是内存地址,当您完成内存时需要将其传递给 free。
但是,下一行将p = "Hello";字符串文字“Hello”(表示存在于 address 25000)的地址放入 p 中。
因此,当您执行时,free(p)您正在尝试释放25000不是由 malloc 分配的。
OTOH,当您strcpy将字符串“Hello”复制到以 p 开头的地址中(即95000)。在 strcpy 之后p仍然存在95000。
并free(p)释放正确的内存。
你也可以避免malloc和使用
char *p = "Hello";
Run Code Online (Sandbox Code Playgroud)
但是,在此方法中,您不能修改字符串。
即,如果在此之后您*p = 'B'将字符串更改为Bello,它将成为未定义的操作。情况并非如此malloc。
如果相反,您使用
char p[] = "Hello";
Run Code Online (Sandbox Code Playgroud)
或者
char p[10] = "Hello";
Run Code Online (Sandbox Code Playgroud)
你会得到一个不需要freed的可修改字符串。