簡體   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