2012-07-18 86 views
0

您好我有下面的代碼指針在C結構體變量

#include <stdio.h> 
#include <conio.h> 
typedef struct test 
{ 
    int a; 
    int b; 
    int c[10]; 
}tester; 

typedef struct done 
{ 
    tester* t; 
    int nn; 
}doner; 

void main() 
{ 
    doner d; 
    d.t = (tester*)malloc(sizeof(d.t)); 
    d.t->a = 10; 
    d.t->c[0] = 10; 
    printf("%d\n", d.t->a); 
    getch(); 
    return; 
} 

我認爲聲明:

d.t = (tester*)malloc(sizeof(d.t)); 

不正確,它應該是:

d.t = (tester*)malloc(sizeof(tester)); 

但是當我運行這段代碼不會崩潰,請讓我這是爲什麼。

+0

有什麼問題,每個bug都不能保證崩潰 – perreal 2012-07-18 09:51:20

+0

1)conio.h是一個非標準的頭文件。 2)main()應該返回int。 3)不要投射malloc()的返回值。4)#include 5)'d.t = malloc(sizeof * d.t);' – wildplasser 2012-07-18 09:57:54

回答

1

它沒有崩潰的事實是因爲它有未定義的行爲。正確的代碼是第二個,但不需要投射。

d.t = malloc(sizeof(tester)); 

另外,你需要釋放malloc分配指針。

在許多系統上,寫入malloc緩衝區時不會檢查堆,但只有釋放分配的內存時纔會檢查堆。在這種情況下,釋放內存時可能會發生某種類型的崩潰。

0

是的,你說得對。它應該是sizeof(tester),因爲d.t只是一個指針。

現在如果你寫sizeof(d.t)你調用Undefined Behavior這不是崩潰的保證。該程序可能運行正常,運行不正確,崩潰或訂購比薩餅。無法保證未定義行爲的程序會發生什麼情況,即使在構建它的結構之前。

由於free荷蘭國際集團的malloc版內存 - 在這個小樣本程序,你不必擔心,因爲系統會在程序退出後釋放內存,但一般而言,您應該嘗試任何你自由」已被分配以避免較大程序中的內存泄漏。

1

它沒有崩潰的事實是這些內存分配錯誤如此陰險和難以檢測的重要原因。你的程序只分配一個結構,並沒有填充它,所以它運行超過分配給它的內存量的事實不會影響其他任何東西。

如果你的程序更加使用動態分配的內存中,然後要麼因爲你的結構改寫堆的鏈接程序寫作的元數據,或其他部件自己malloc分配到malloc/free的通話將觸發崩潰數據會覆蓋你的結構。無論哪種方式,不漂亮。

0

默認情況下,鏈接器要求操作系統在啓動時爲程序分配1MiB的(堆棧)內存。你的程序不會崩潰,因爲所有的引用仍然在你的程序的操作系統保留的相同的內存(相同的地址空間)。從技術上講,你沒有分配內存,但由於指針仍然在有效的內存範圍內,所以你的程序可以訪問它。 這就像在大多數情況下可以寫入d.t-> c [10](儘管有效索引爲0-9)。 當使用指針對應於分配內存外的內存位置時,會發生崩潰。谷歌頁面錯誤的詳細瞭解,如果你有興趣。