提问人:mariekart42 提问时间:6/19/2022 最后编辑:chqrliemariekart42 更新时间:6/19/2022 访问量:175
使用函数 malloc() 和 free(),初始化指针出现问题
using function malloc() and free(), problems with initialized pointer
问:
我对编码并不陌生,但我遇到了一个我无法向自己解释的问题。
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *test;
test = (char *)calloc(15, sizeof(char));
// test = "Wurstbrot";
free(test);
}
如果我编译这个,就会被错误定位并直接释放(我所期望的)。
但是,如果我取消注释注释,则在编译时会出现此错误:test
a.out(28953,0x104403dc0) malloc: *** error for object 0x10365cfae: pointer being freed was not allocated
a.out(28953,0x104403dc0) malloc: *** set a breakpoint in malloc_error_break to debug
zsh: abort ./a.out
当我删除该功能时,它将再次工作。free
我现在的问题是:为什么释放初始化的指针在这里有问题?
答:
free
必须向 、、 或其他堆分配函数分配的块传递空指针或有效指针。malloc()
calloc()
realloc()
strdup()
如果取消注释,则指针将指向静态数据,字符串文字 .将此地址传递给具有未定义的行为。test = "Wurstbrot";
"Wurstbrot"
free()
传递未初始化也会有未定义的行为。如果幸运的话,这个未初始化的变量可能恰好包含一个空指针,因此不会导致...未定义的行为是未定义的,任何事情都可能发生,包括没有可见的副作用。运行时错误(例如 C 库报告的错误)实际上对于查找错误非常有用。事后看来,没有副作用可能不是运气。test
free()
当我们一步一步地分析程序运行时:
A) 程序开始运行前的初始化:
在堆栈上分配一个内存空间,并在该内存空间上放置字符串“Wurstbrot” + '\0'。假设,为字符串分配的内存从 ;即堆栈内存状态如下图所示;AAAA:0000
address value
AAAA:0000 W
AAAA:0001 u
AAAA:0002 r
...
AAAA:0007 o
AAAA:0008 t
AAAA:0009 0 // that's a zero
B) 当程序开始运行时:
第 1 行:创建指针变量。此变量位于堆栈上,未初始化。对于 32 位系统,此变量位于堆栈上(例如,at address to 并包含一些垃圾值,例如指向某个随机内存。AAAA:0020
AAAA:0023
DBAC:5782
address value
AAAA:0020 DB
AAAA:0021 AC
AAAA:0022 57
AAAA:0023 82
第 2 行:
操作系统分配一个长度为 15 字节的内存空间(可能在堆上),并将起始值传递给程序(假设它从 开始)。此值将分配给指针变量,并且第 1 行上的指针值将更改为 。DDDD:0000
DDDD:0000
address value
AAAA:0020 DD
AAAA:0021 DD
AAAA:0022 00
AAAA:0023 00
第 3 行:该行将指针的值重置为指向在步骤 (A) 中分配的内存。从现在开始,指针变量不再指向堆上分配的内存空间,而是指向堆栈上初始化的内存空间。test = "Wurstbrot";
test
address value
AAAA:0020 AA
AAAA:0021 AA
AAAA:0022 00
AAAA:0023 00
第 4 行:当然,这一行会引起错误。它尝试释放步骤 (A) 中初始化的内存空间,而不是在步骤 (B)/1 中分配的内存空间。
解决方案:
第 3 行应为:strcpy(test, "Wurstbrot");
评论
=
strcpy
calloc
free
calloc
malloc
calloc
calloc
free