为什么这段代码在释放指针时会给出运行时异常

Pra*_*ari 2 c runtime

我有简单的代码,

#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)

此代码在终止时给出运行时异常.以下是错误最快的,


Microsoft Visual C++调试库

调试断言失败!

程序:...\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++文档.

(按"重试"调试应用程序)

中止重试忽略

Luc*_*ore 6

p = "Hello";使得p指向一个字符串字面量并丢弃先前分配的值.你不能free是字符串文字.你无法修改它.

如果你想p保留该字符串,只需使用

char* p = "Hello";
Run Code Online (Sandbox Code Playgroud)

要么

char p[] = "Hello";
Run Code Online (Sandbox Code Playgroud)

如果你打算修改它.

两者都不需要free.

  • @PranitPKothari它会泄漏. (3认同)

use*_*353 5

这就是将 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的可修改字符串。