2012-04-02 3 views
0

У меня есть установка двумерного указателя, представляющая сетку, сетка состоит из столбцов, содержащих 1/0 или нулевые столбцы (т. Е. Не содержит 1 в любой ячейке). Эта функция вращает сетку на 90 градусов по часовой стрелке и работает за исключением ...C 2D-массив, вращающийся

Я думаю, что мой malloc может ошибаться, так как он работает, но я получаю много ошибок при обнаружении пикета в dmalloc.

Я выделяю неправильное количество памяти?

Также я хотел поменять значения * width и * height, чтобы представить новую ширину и высоту сетки, но когда я пробую это, программа просто переходит к второму вращению.

+0

Любопытство, есть причина, по которой вы не malloc всей сетке сразу, а malloc это линии за строкой? – thb

+0

Но он может освободить() всю память, не так ли? К концу функции не может быть ничего, поэтому он может segfault (при втором вращении). – gbulmer

+0

Вставляя диагностические printfs в стратегических точках вашего кода, можете ли вы определить, где произошла ошибка? – thb

ответ

1

So * ширина размер первого измерения туринг, поэтому она должна быть размер второго измерения 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; 
    } 

Кроме того, он должен не освобождает любой хранения NEWG, если вы хотите, чтобы вернуть значения из spin()

Edit: я до сих пор некоторые из этих надоедливых * ширина и высота * неоднозначными. Сожалею. Я настоятельно рекомендую, чтобы имена были связаны с тем, о чем они говорят, 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

Я понимаю это, но даже при использовании * height вместо * width в начальном malloc я получаю много утечек памяти. – user1277546

+0

Извините, я сделал незавершенную работу - пожалуйста, взгляните на мой код. – gbulmer

1

Посмотрите еще раз на код, который вращает сетку. Я не думаю, что вы когда-либо хотели бы смешать 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. 
+0

Этот бит отлично работает, я не вижу, что с ним не так? – user1277546

+0

@ user1277546: Ну, учтите: максимальное значение 'y' в этом цикле равно' * height - 1'. Когда 'y' имеет это значение, каково значение' * width - 1 - y'? Разве это не '* height - * width', что может быть отрицательным числом? – thb

+0

@Adam Liss В сетке orig будут установлены столбцы с нулевым значением, поэтому я думаю, что текущий способ работает одинаково? – user1277546

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; 
} 

Дайте мне знать, если возникнут какие-либо проблемы.

Смежные вопросы