2013-10-05 36 views
0

當我改變函數中我調用malloc的位置時,出現分段錯誤。 此代碼正常工作並打印「結束\ n」。從哪裏調用malloc從哪裏來都沒關係? - c

#include <stdio.h> 
#include <stdlib.h> 

int main() {  

    int **pptr; 
    if (!(*pptr = malloc(4))) 
     return 1; 

    int *ptr; 
    if (!(ptr = malloc(4))) 
     return 1; 

    ptr[0]= 1; 
    printf("Point 1\n"); 

    free(ptr); 

    (*pptr)[0] = 1; 

    free(*pptr); 
    printf("End\n"); 
    return 0; 
} 

但是,這個看似等價的代碼在分段錯誤的「點1 \ n」之前結束。

#include <stdio.h> 
#include <stdlib.h> 

int main() {  

    int *ptr; 
    if (!(ptr = malloc(4))) 
     return 1; 

    ptr[0]= 1; 
    printf("Point 1\n"); 

    free(ptr); 

    int **pptr; 
    if (!(*pptr = malloc(4))) 
     return 1; 
    (*pptr)[0] = 1; 

    free(*pptr); 
    printf("End\n"); 
    return 0; 
} 

我在想什麼? (我是一個初學者)

其他信息:我在Ubuntu下使用gcc使用Netbeans。

+0

首先閱讀如何使用'malloc'! – haccks

+0

我讀了其他東西,其中包括http://www.cplusplus.com/reference/cstdlib/malloc/的參考頁面。對不起,這個愚蠢的錯誤,但我想我分配4個字節(我的系統中的一個int的大小),然後將指針指向該位置指向我的指針,然後檢查它是否爲null,以防萬一。也許其他新手也有同樣的困惑。 – niic

回答

5

在這兩種方案,你在這裏調用未定義行爲:

int **pptr; 
if (!(*pptr = malloc(4))) 
    return 1; 

pptr是被dereferenced存儲由malloc返回的指針未初始化的指針。由於未定義的行爲,第一個恰好看起來像它正在工作,但是正在破壞內存pptr正好指向。

第二次失敗,因爲pptr碰巧指向無法寫入的內存區域。

另外,由於在上面的代碼中分配了int*,所以malloc(4)是不安全的。使用malloc(sizeof(int*))。例如,64位系統通常具有8字節指針。

2

什麼是sizeof(int)?如果它> 4,那麼是的,你正在調用未定義的行爲。

當調用未定義的行爲時,是的,訂單可能很重要。任何事情都很重要。無論您的系統時間在程序運行開始時是偶數還是奇數都可以(但可能不會)重要。這就是未定義的手段。

在這種情況下,我懷疑這兩個malloc會以某種方式通知編譯器需要分配哪些內存,並且在第一種情況下,您碰巧覆蓋到可寫空間,因此「很幸運」。當然,在更大的計劃中,你會感到不幸,因爲我懷疑你失敗了。

無論如何,首先讓程序正確,然後找出你的UB是什麼,然後找出可能導致它的實現細節。