繁体   English   中英

使用函数 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()具有未定义的行为。

通过未初始化的test也会有未定义的行为。 如果幸运的话,这个未初始化的变量可能恰好包含一个空指针,因此不会导致free()出现问题...未定义的行为是未定义的,任何事情都可能发生,包括没有可见的副作用。 诸如 C 库报告的运行时错误实际上对于查找错误非常有用。 事后看来,没有副作用可能是没有运气。

当我们逐步分析程序运行时:

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 位系统,此变量位于堆栈上(例如,在地址AAAA:0020AAAA:0023并包含一些垃圾值,如DBAC:5782指向一些随机内存。

address     value
AAAA:0020   DB
AAAA:0021   AC
AAAA:0022   57
AAAA:0023   82

第 2 行:操作系统分配一个长度为 15 个字节的内存空间(可能在堆上),并将起始值交给程序(比如从DDDD:0000开始)。 该值分配给您的指针变量,第 1 行的指针值更改为DDDD:0000

address     value
AAAA:0020   DD
AAAA:0021   DD
AAAA:0022   00
AAAA:0023   00

第 3 行test = "Wurstbrot"; 行重置指针的值以指向在步骤 (A) 分配的内存。 从现在开始,你的指针变量test不再指向堆上分配的内存空间,而是栈上初始化的内存空间。

address     value
AAAA:0020   AA
AAAA:0021   AA
AAAA:0022   00
AAAA:0023   00

第 4行:这一行当然会引发错误。 它试图在步骤 (A) 释放初始化的内存空间,而不是在步骤 (B)/1 分配的内存空间。

解决方案

第 3 行应为: strcpy(test, "Wurstbrot");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM