2012-04-02 8 views
0

Ich habe einen 2D-Zeiger-Setup, der ein Gitter darstellt, das Gitter besteht aus Spalten, die 1/0 oder Null-Spalten enthalten (d. H. In keiner Zelle 1 enthalten). Diese Funktion dreht das Gitter um 90 Grad im Uhrzeigersinn, und funktioniert außer ...C 2D-Array rotierend

Ich denke, meine Malloc könnte falsch sein, wie es funktioniert, aber ich bekomme viele über Lattenzaun Fehler in dmalloc.

Ordne ich falsche Speichermengen zu?

Auch ich wollte die Werte von * width und * height tauschen, um die neue Breite und Höhe des Rasters darzustellen, aber wenn ich das versuche, segredest das Programm nur auf dem zweiten Dreh.

+0

Aus Neugier, gibt es einen Grund, warum Sie nicht das gesamte Netz auf einmal malloc, sondern Malloc es Zeile für Zeile? – thb

+0

Aber es kann die gesamte Speicher frei(), nicht wahr? Am Ende der Funktion ist möglicherweise nichts mehr vorhanden und kann segfault (beim zweiten Dreh). – gbulmer

+0

Durch Einfügen von diagnostischen printfs an strategischen Punkten in Ihrem Code können Sie genau feststellen, wo der Fehler auftritt. – thb

Antwort

1

So * Breite ist die Dimension der ersten Dimension des orig, soll es so sein sollte die Größe der zweiten Dimension von newg.

Ähnlich sollte die Höhe die Größe von Newgs zuerst sein, und daher wurden die zwei Sätze von malloc Größen falsch herum umgedreht.

Ich denke, es wäre klarer, die Werte orig_max_x und orig_max_y zu nennen, dann sollte es klar sein, wenn die Funktion die Werte falsch herum verwendet.

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

Ferner sollte es keine von newg Storage-frei, wenn Sie Werte zurückgeben möchten von spin()

Edit: Ich hatte noch einige dieser lästigen * Breite und Höhe * gemischt. Es tut uns leid. Ich schlage vor, die Namen sollten sich auf die Sache beziehen, über die sie sprechen, orig_width, orig_height wäre mir geholfen, den Code zu lesen.

Dies ist wahrscheinlich, wie ich es tun würde:

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

WARNUNG Ungeprüfte Code - Spaß für alle :-)

ich es nicht glaube, ist Aufgabe des Spin kostenlos orig . Ich würde es vorziehen, einfach Platz zu machen, um das Ergebnis des Drehens zu halten. Um die Dinge besser zu machen, habe ich ein Rechteck in seine eigene Funktion gebracht. Ähnlich möchte ich immer, dass die Rechtecke einheitlich zugewiesen werden, so dass dies eine eigene Funktion wäre.

+0

Ich verstehe das, aber selbst bei der Verwendung von * Höhe statt * Breite in der ursprünglichen Malloc bekomme ich viele Speicherlecks. – user1277546

+0

Entschuldigung - Ich habe einen unvollständigen Job gemacht - bitte schauen Sie sich noch einmal meinen Code an. – gbulmer

1

Sehen Sie sich noch einmal den Code an, der das Raster dreht. Ich glaube nicht, dass Sie jemals x und y Koordinaten mischen wollen, so dass ein Index wie *width - 1 - y verdächtig aussieht. Angenommen, *width = 3 und *height = 5. Dann reicht y von 0 bis 4, und Sie können mit newg[3 - 1 - 4] = newg[-2] enden.

Auch wenn Sie orig zugewiesen haben die gleiche Weise newg zugewiesen werden Sie es so befreien müssen:

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

Dieses Bit funktioniert gut, ich sehe nicht, was ist los damit? – user1277546

+0

@ user1277546: Nun, bedenken Sie: Der maximale Wert von 'y' in dieser Schleife ist '* height - 1'. Wenn 'y' diesen Wert hat, was ist der Wert von' * width - 1 - y'? Ist es nicht '* height - * width', was könnte eine negative Zahl sein? – thb

+0

@Adam Liss Das Orig Grid wird Spalten auf Null gesetzt haben, also denke ich, dass der aktuelle Weg der gleiche ist? – user1277546

0

Ich habe das gerade schnell geschrieben und es schien gut zu funktionieren mit den paar Tests, die ich darauf ausgeführt habe.

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

Lassen Sie mich wissen, wenn es irgendwelche Probleme gibt.