我有一個代表網格的2D指針設置,網格由包含1/0或空列的列組成(即在任何單元格中不包含1)。此函數順時針旋轉網格90deg,除了...C二維數組旋轉
我認爲我的malloc可能是錯誤的,因爲它的工作原理,但我得到了很多超過dmalloc的柵欄錯誤。
我是否分配了不正確的內存量?
另外我想交換* width和* height的值來表示網格的新寬度和高度,但是當我嘗試這個時,程序只是在第二次旋轉時發生segfaults。
我有一個代表網格的2D指針設置,網格由包含1/0或空列的列組成(即在任何單元格中不包含1)。此函數順時針旋轉網格90deg,除了...C二維數組旋轉
我認爲我的malloc可能是錯誤的,因爲它的工作原理,但我得到了很多超過dmalloc的柵欄錯誤。
我是否分配了不正確的內存量?
另外我想交換* width和* height的值來表示網格的新寬度和高度,但是當我嘗試這個時,程序只是在第二次旋轉時發生segfaults。
所以*寬度原稿的第一個維度的尺寸,所以它應該是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;
}
警告未經測試的代碼 - 一些有趣的所有:-)
我不認爲它是旋轉的作業免費原稿。我寧願它只是騰出空間來保持旋轉的結果。所以爲了讓事情更加整潔,我把一個矩形放到了自己的函數中。同樣,我總是希望矩形分配一致,所以這將是它自己的功能。
我明白這一點,但即使在初始malloc中使用* height而不是* width,我會發生很多內存泄漏。 – user1277546 2012-04-02 00:50:19
對不起 - 我做了一個不完整的工作 - 請再看看我的代碼。 – gbulmer 2012-04-02 00:52:50
再看看旋轉網格的代碼。我不認爲你曾經想要混合x
和y
的座標,因此像*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.
這一點工作正常,我沒有看到它有什麼問題嗎? – user1277546 2012-04-02 00:20:57
@ user1277546:好的,請考慮:該循環中'y'的最大值是'* height - 1'。當'y'具有該值時,'* width - 1 - y'的值是多少?是不是'*高度 - *寬度,這可能是一個負數? – thb 2012-04-02 00:25:51
@Adam Liss原始網格將列設置爲空,所以我認爲目前的方式是一樣的? – user1277546 2012-04-02 00:28:57
我剛寫了這個很快,它似乎工作正常與我運行它的幾個測試。
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;
}
讓我知道是否有任何問題。
好奇心,是不是有一個原因你一次不malloc整個網格,而是malloc它一行一行? – thb 2012-04-02 00:12:33
但它可以釋放()所有的內存,不是嗎?在函數結束時,可能沒有剩下任何東西,所以它可以分段錯誤(在第二次旋轉時)。 – gbulmer 2012-04-02 00:13:11
通過在代碼中的關鍵點插入診斷printfs,可以確定故障發生的位置? – thb 2012-04-02 00:15:55