2011-10-05 66 views
1

所以我在我的程序中使用malloc,然後在程序內部的一個方法中重新分配。在我多次調用這個方法後,我會得到一個「Segmentation fault(核心轉儲)」。例如,當我的指針從0x25d7d60或0x223fae0(或由7位數字(0xHHHHHHH)代表的任何地址)變爲0x7f47d370a010(超過7位數字)時,我意識到出於某種原因,出現了段錯誤在realloc調用中,realloc甚至不會返回NULL。我通過簡單地使用malloc和memcpy來解決這個問題。然而,我很困惑,爲什麼發生這種情況,並想看看是否有任何用戶的stackoverflow可以揭示爲什麼發生這種情況。Segfault with realloc

感謝

下面是相關代碼:

unsigned int* myArray; 
unsigned int num_ints; 

int main() 
{ 

    num_ints = 100; 
    if((myArray =(unsigned int*) malloc(sizeof(unsigned int)*(num_ints)*3))==NULL) 
    { 
    std::cout << "Malloc failed!" << std::endl; 
    return false; 
    } 

    . 
    . 
    . 

    //This called when n key is pressed (code left out) 
    methodName(); 
return true; 
} 

void methodName() 
{ 

if((myArray =(unsigned int*) realloc(myArray,sizeof(unsigned int)*(num_ints*4)*3))==NULL) 
{ 
    std::cout << "Realloc failed!" << std::endl; 
    exit(0); 
} 

} 
+0

請將代碼顯示出來 – phoxis

+0

請代碼 –

+0

它應該是C還是C++?爲什麼它被標記爲C但仍使用'std :: cout'? – AnT

回答

5

有一個很好的機會,通過調用「的realloc裏面的程序方法中」,實際上是加載到一個局部變量然後扔掉,你的程序繼續使用舊指針(現在已經釋放)。

我們需要看到代碼是確定的,但以我的經驗來看,這是分配錯誤的主要原因之一。


根據您所展示的內容,您所做的沒有任何問題。它與此代碼實際上是相同的:

#include <iostream> 
#include <cstdlib> 
int sz = 1000; 
int *buffer = 0; 
static int methodName (void) { 
    if (sz == 100000) 
     sz = 100; 
    sz = sz * 10; 
    if ((buffer = (int*)realloc (buffer, sz)) == 0) { 
     std::cout << "Realloc error" << std::endl; 
     return 1; 
    } 
    return 0; 
} 
int main(void) { 
    int i; 
    if ((buffer = (int*)malloc (sz)) == 0) { 
     std::cout << "Alloc error" << std::endl; 
     return 1; 
    } 
    for (i = 0; i < 10000000; i++) 
     if (methodName() != 0) 
      return 1; 
    std::cout << "All okay" << std::endl; 
    return 0; 
} 

它完美地工作,做了一千萬次重新分配。

所以問題出在你向我們展示的東西之外,也許是一個編譯器bug(如果你使用主流編譯器的話不太可能)或者代碼中其他地方的內存損壞。

+0

我在帖子中添加了代碼。它不是我使用的實際代碼,但非常相似。我使用的代碼將指針作爲全局變量。 – Matt

+0

@Matt,我發現你發佈的代碼沒有問題。您應該發佈真實代碼或至少發佈問題的代碼(最好是最小的變體)。 – paxdiablo

+0

我同意。這是我的實際代碼,除了我更改了myArray和num_ints變量名稱以及methodName的名稱。 – Matt

3

如果realloc改變數組的地址,然後myarr在功能範圍(本地)獲得新的價值,它不會在main

+---------+ 
| val1 | = malloc (whatever); <--------------------------+ 
+---------+              | 
|myarr |              | 
+---------+              | 
|addr_main|              | 
+----+----+              | 
    |               | 
    |               | 
    |            (NO EFFECT on here) 
(value of the myaddr 'val1')         | 
(in main passed by value)          | 
(to function)             | 
    |               | 
    +-------+             | 
      |             | 
      v             | 
methodname (myarr, someint)          | 
      |             | 
      |             | 
      V             | 
     +---------+            | 
     | val1 | = realloc (myarr, whatever)  ---------+ 
     +---------+  
     |myarr | if 'realloc' returns a new address 
     +---------+ it will only overwrite 'val1' with some 'val2' 
     |addr_func| in this LOCAL copy with address 'addr_func' 
     +---------+ 
      | 
      | 
      V 
    (destroyed after function return) 
+0

好的,這不是我的實際代碼...我只是在飛行中做到了這一點。我的實際代碼是在我的學校計算機上,而不是這個。在我的實際代碼myArray是一個全局變量 – Matt

+0

然後它應該工作。 – phoxis

+0

我知道它應該和它的工作,直到我點擊n鍵來獲得更多的內存像十次,當前內存的地址是0xHHHHHHH,第一次是0xHHHHHHHHHHHH,當它失敗。它適用於我的Mac,當我登錄Linux機器時,而不是當我在Linux機器上時。 – Matt

0

你沒有改變而改變的myarr變量myArr在主要範圍內,realloc可能會返回一個新地址,舊地址無效。

+0

好吧,這不是我的實際代碼...我只是在飛行中做到了這一點。我的實際代碼是在我的學校計算機上,而不是這個。在我的實際代碼中myArray是一個全局變量 – Matt

0

問題是您的methodName函數將新指針指派給它的本地副本myArray。

速戰速決是使myArray的一個指針的指針,像這樣:

void methodName(unsigned int **myArray, unsigned int num_ints) 
{ 
    if((*myArray = (unsigned int *)realloc((*myArray), sizeof(unsigned int)*(num_ints*4)*3)) == NULL) 
    { 
     std::cout << "Realloc failed!" << std::endl; 
     exit(0); 
    } 
} 

,然後通過傳遞myArr,該的地址稱之爲:

methodName(&myArr, n_ints); 

方法名這樣得到內存的地址爲main() s myArr,以便它可以寫入它。

正如你雖然可以看到,其功能參數輸出值可以得到一點毛茸茸的,所以我建議,而不是return荷蘭國際集團的新地址:

unsigned int *methodName(unsigned int *myArray, unsigned int num_ints) 
{ 
    return (unsigned int *)realloc(myArray, sizeof(unsigned int) * (num_ints * 4) *3); 
} 

然後,它只是一個在main覆蓋myArr的事情:

myArr = methodName(myArr, n_ints); 
+0

好吧,這不是我的實際代碼...我只是在飛行中做到了這一點。我的實際代碼是在我的學校計算機上,而不是這個。在我的實際代碼中,myArray是一個全局變量 – Matt

+0

@Matt在這裏發佈問題時,這些細節非常重要。如果你修復問題中的代碼,我會更新這個答案。 –

+0

我更新了問題中的代碼。對不起,關於 – Matt