2012-04-02 175 views
0

我有一個代表網格的2D指針設置,網格由包含1/0或空列的列組成(即在任何單元格中不包含1)。此函數順時針旋轉網格90deg,除了...C二維數組旋轉

我認爲我的malloc可能是錯誤的,因爲它的工作原理,但我得到了很多超過dmalloc的柵欄錯誤。

我是否分配了不正確的內存量?

另外我想交換* width和* height的值來表示網格的新寬度和高度,但是當我嘗試這個時,程序只是在第二次旋轉時發生segfaults。

+0

好奇心,是不是有一個原因你一次不malloc整個網格,而是malloc它一行一行? – thb 2012-04-02 00:12:33

+0

但它可以釋放()所有的內存,不是嗎?在函數結束時,可能沒有剩下任何東西,所以它可以分段錯誤(在第二次旋轉時)。 – gbulmer 2012-04-02 00:13:11

+0

通過在代碼中的關鍵點插入診斷printfs,可以確定故障發生的位置? – thb 2012-04-02 00:15:55

回答

1

所以*寬度原稿的第一個維度的尺寸,所以它應該是newg的第二個維度的大小。

同樣*高度應該是newg的第一個大小,因此兩組malloc大小被錯誤地翻轉了。

我認爲將orig_max_x和orig_max_y這個值命名會更加清楚,那麼應該清楚函數是否使用了錯誤的值。

newg = malloc (*height * sizeof(char *)); 

    // Initialise each column 
    for (x = 0; x < *height; x++) { 
     newg[x] = malloc (*width); 
     for (y = 0; y < *width; y++) 
      newg[x][y] = 0; 
    } 

此外,應該沒有,如果你想從spin()

編輯返回值釋放newg的存儲的任何:我仍然有一些那些討厭*寬*和混合高度。抱歉。 我強烈建議名稱應該與他們談論的東西有關,orig_width, orig_height會幫助我閱讀代碼。

這可能是我會怎麼做:

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

char** alloc_rectangle(int *width, int *height); 
void free_rectangle(char **orig, int *width); 
char** spin (char **orig, int *width, int *height); 

int main (int argc, const char * argv[]) { 
    int width = 20; 
    int height = 30; 

    char** orig = alloc_rectangle(&width, &height); 
    char** newg = spin(orig, &width, &height); 


    return 0; 
} 

char** alloc_rectangle(int *width, int *height) 
{ 
    char **newg = calloc (*width, sizeof(char *)); 

    // Initialise each column 
    for (int x = 0; x < *width; x++) { 
     newg[x] = calloc (*height, sizeof(char)); 
    } 
    return newg; 
} 

void free_rectangle(char **orig, int *width) 
{ 
    // free memory for old grid 
    for (int x = 0; x < *width; x++) { 
     if (orig[x] != NULL) { 
      free (orig[x]); 
     } 
    } 

    free (orig); 
} 

char** spin (char **orig, int *width, int *height) 
{ 
    int x; 
    int y; 

    char **newg = alloc_rectangle(height, width); 

    // Rotate 
    for (x = 0; x < *width; x++) { 
     for (y = 0; y < *height; y++) 
      if (orig[x] != NULL) 
       newg[*height - 1 - y][x] = orig[x][y]; 
    } 

    return newg; 
} 

警告未經測試的代碼 - 一些有趣的所有:-)

我不認爲它是旋轉的作業免費原稿。我寧願它只是騰出空間來保持旋轉的結果。所以爲了讓事情更加整潔,我把一個矩形放到了自己的函數中。同樣,我總是希望矩形分配一致,所以這將是它自己的功能。

+0

我明白這一點,但即使在初始malloc中使用* height而不是* width,我會發生很多內存泄漏。 – user1277546 2012-04-02 00:50:19

+0

對不起 - 我做了一個不完整的工作 - 請再看看我的代碼。 – gbulmer 2012-04-02 00:52:50

1

再看看旋轉網格的代碼。我不認爲你曾經想要混合xy的座標,因此像*width - 1 - y這樣的索引看起來很可疑。例如,假設*width = 3*height = 5。然後y的範圍從0到4,您可以以newg[3 - 1 - 4] = newg[-2]結束。

另外,如果你已經分配orig你分配newg你需要釋放它像這樣以同樣的方式:

for (x=0; x < *width; x++) { 
    free (orig[x]); // Free the individual columns 
} 
free (orig); // Free the array of pointers. 
+0

這一點工作正常,我沒有看到它有什麼問題嗎? – user1277546 2012-04-02 00:20:57

+0

@ user1277546:好的,請考慮:該循環中'y'的最大值是'* height - 1'。當'y'具有該值時,'* width - 1 - y'的值是多少?是不是'*高度 - *寬度,這可能是一個負數? – thb 2012-04-02 00:25:51

+0

@Adam Liss原始網格將列設置爲空,所以我認爲目前的方式是一樣的? – user1277546 2012-04-02 00:28:57

0

我剛寫了這個很快,它似乎工作正常與我運行它的幾個測試。

char **rotate(char **original, int *width, int *height) 
{ 
    int t_width = *height; 
    int t_height = *width; 

    char **newgrid = (char**)calloc(t_height, sizeof(char*)); 

    for(int y = 0; y < t_height; y++) 
    { 
     newgrid[y] = (char*)calloc(t_width, sizeof(char)); 
     for(int x = 0; x < t_width; x++) 
      newgrid[y][x] = original[x][y];   
    } 

    for(int y = 0; y < *height; y++) 
     free(original[y]); 
    free(original); 

    *width = t_width; 
    *height = t_height; 

    return newgrid; 
} 

讓我知道是否有任何問題。