2012-11-24 43 views
0

我有一個2D數組的程序。首先,我分配陣列是這樣的:程序在重新分配內存時導致內存損壞

char **crossword; 
crossword = (char **) malloc(n* sizeof(*crossword)); 
for (i = 0; i < n; i++) 
    crossword[i] = (char *)malloc(n); 

其中n = 50。

然後我有功能,即從stdin讀取字符串。問題是,我不知道這些字符串會有多少或多長時間。

void read(char **p,int *n) 
{ 
char tmp = 0,prevtmp = 0; 
int i = 0, j = 0,x; 

while (1) 
{ 
    prevtmp = tmp; 
    tmp = getchar(); 
    if ((tmp == '\n' && prevtmp == '\n') || feof (stdin)) 
    { 
     *n = i; 
     break; 
    } 
    if (tmp == '\n') 
    { 
     p[i][j] = '\0'; 
     i++; 
     if (i == *n) 
     { 
      p = (char **) realloc(p, 2*i); // if there is more strings than space for them, allocate more memory. 
      for (x = i; x < 2*i; x++) 
       p[x] = (char *) malloc (*n); 

      *n *= 2; 
     } 
     j = 0; 
     continue; 
    } 
    p[i][j] = tmp; 
    j++; 
    if (j == *n) 
     p[i] = (char *)realloc(p[i], 2*j); //same as above 
} 
} 

函數被調用是這樣的:

read(crossword,&n); 

此功能工作正常,在沒有必要的realloc(有小於50串,每一個小於50個字符)。但對於大的投入,這將失敗,並

*** glibc detected *** ./a.out: malloc(): memory corruption (fast): 0x00000000014282f0 *** error. 

我想我的問題是,我的realloc更多的內存部分,這裏是從Valgrind的輸出:

==8885== Invalid write of size 1 
==8885== at 0x40084C: read (in /home/xerw/Dropbox/CVUT/PROGTEST/du6/a.out) 
==8885== by 0x40177F: main (in /home/xerw/Dropbox/CVUT/PROGTEST/du6/a.out) 
==8885== Address 0x51f2b88 is not stack'd, malloc'd or (recently) free'd 
==8885== 
==8885== Invalid write of size 8 
==8885== at 0x4008A6: read (in /home/xerw/Dropbox/CVUT/PROGTEST/du6/a.out) 
==8885== by 0x40177F: main (in /home/xerw/Dropbox/CVUT/PROGTEST/du6/a.out) 
==8885== Address 0x51f4f00 is not stack'd, malloc'd or (recently) free'd 

valgrind: m_mallocfree.c:266 (mk_plain_bszB): Assertion 'bszB != 0' failed. 
valgrind: This is probably caused by your program erroneously writing past the 
end of a heap block and corrupting heap metadata. If you fix any 
invalid writes reported by Memcheck, this assertion failure will 
probably go away. Please try that before reporting this as a bug. 

==8885== at 0x3804C6CF: ??? (in /usr/lib/valgrind/memcheck-amd64-linux) 
==8885== by 0x3804C812: ??? (in /usr/lib/valgrind/memcheck-amd64-linux) 
==8885== by 0x38000883: ??? (in /usr/lib/valgrind/memcheck-amd64-linux) 
==8885== by 0x380574EA: ??? (in /usr/lib/valgrind/memcheck-amd64-linux) 
==8885== by 0x38057E03: ??? (in /usr/lib/valgrind/memcheck-amd64-linux) 
==8885== by 0x380212DC: ??? (in /usr/lib/valgrind/memcheck-amd64-linux) 
==8885== by 0x3802146A: ??? (in /usr/lib/valgrind/memcheck-amd64-linux) 
==8885== by 0x3808F656: ??? (in /usr/lib/valgrind/memcheck-amd64-linux) 
==8885== by 0x3809E68C: ??? (in /usr/lib/valgrind/memcheck-amd64-linux) 

sched status: 
    running_tid=1 

Thread 1: status = VgTs_Runnable 
==8885== at 0x4C2B3F8: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==8885== by 0x4008A5: read (in /home/xerw/Dropbox/CVUT/PROGTEST/du6/a.out) 
==8885== by 0x40177F: main (in /home/xerw/Dropbox/CVUT/PROGTEST/du6/a.out) 

我一直在嘗試與指針很短的時間,所以我不知道什麼是錯的。我一直試圖解決這個問題幾個小時,但我沒有提出任何問題。

我在做什麼錯?

+0

什麼是填字遊戲的類型? – piokuc

+0

char **填字遊戲,編輯我的帖子。 – isklenar

+0

你在你的代碼中執行'p =(char **)realloc(p,2 * i);'。 'p'指向填字遊戲嗎?如果是這樣,你已經分配了縱橫字符,大小爲'n * sizeof(*縱橫字謎)'。那麼'2 * i'是否正確?順便說一下,調用realloc並將其結果指定給您直接重新分配的指針是不好的 - 如果realloc()失敗,它會泄漏內存,導致原始指針現在丟失。 –

回答

1

的問題似乎是以下行:

p = (char **) realloc(p, 2*i); 

我想這應該是:

p = (char **) realloc(p, (2*i)*sizeof(char*)); 

即要增加數組來保存2*i元素,所以你需要分配2*i乘以char*的大小。

+0

謝謝,解決了,但我的程序仍然崩潰,這次有一個不同的錯誤。我現在正在通過電話發帖,我不記得確切的錯誤,明天早上將會查看。 – isklenar