Legge et int medlem til en C struct bevirker en segfault

stemmer
3

Jeg er fortsatt læring C, og har begynt å bruke den til å generere bilder. Jeg kan ikke finne ut hvorfor en av mine programmer er segfaulting. Her er kildekoden, kuttet ned til 40 linjer:

#include <stdio.h>
#include <stdlib.h>
struct color {
        unsigned char r, g, b;
};
struct image {
        int w, h/*, o*/;
        struct color **data;
};
int main() {
        // Declarations
        int x, y;
        struct color *black;
        struct image *img;
        // Set up color black
        black = (struct color *) malloc(sizeof(struct color *));
        black->r = 0;
        black->g = 0;
        black->b = 0;
        // Set up image img
        img = (struct image *) malloc(sizeof(struct image *));
        img->w = 1;
        img->h = 1;
        /*img->o = 0;*/
        img->data = (struct color **) malloc(img->h * sizeof(struct color *));
        for (y = 0; y < img->h; y++) {
                img->data[y] = (struct color *) malloc(img->w * sizeof(struct color));
        }
        // Fill in img with black
        for (x = 0; x < img->w; x++) {
                for (y = 0; y < img->h; y++) {
                        img->data[y][x].r = black->r;
                        img->data[y][x].g = black->g;
                        img->data[y][x].b = black->b;
                }
        }
        // Free black
        free(black);
        // Free img
        for (y = 0; y < img->h; y++)
                free(img->data[y]);
        free(img->data); // Segfaults
        free(img); // Also segfaults
        return 0;
}

Det kompilerer og kjører fint (med gcc på Ubuntu og på Vista med Cygwin), men uncommenting de to linjene som arbeider med img-> o bryter det. Jeg har en følelse det er relatert til dette forrige spørsmål , men jeg malloc'ing alt som trenger å bli malloc'ed (tror jeg). Eventuelle hjelpe ville være verdsatt.

Publisert på 24/02/2009 klokken 02:01
kilden bruker
På andre språk...                            


4 svar

stemmer
21

Det er en feil i dine malloc uttalelser. Du mallocing en peker og ikke en struct. Dette gir deg bare 4 byte minne i stedet for den faktiske størrelsen som kreves av struct.

black = malloc(sizeof(*black));

Ved tildeling av minne for en peker, må du tildele minne for ting som blir pekt på, ikke den type pekeren. Hvis du bare skrive sizeof(*black)som vist, vil du alltid få den rette typen, selv om den type blackendringer.

Svarte 24/02/2009 kl. 02:04
kilden bruker

stemmer
1

JaredPar har det rette svaret, men hvis du får en segfault, er den første tingen å gjøre å kjøre programmet under Valgrind. Det er en stor hjelp for å håndtere problemer som dette.

BTW, har jeg kastet bort dager på den eksakte feilen. Vær glad du kjørte inn i den tidlig i C-programmering karriere og vil alltid se opp for det i fremtiden.

Svarte 24/02/2009 kl. 02:08
kilden bruker

stemmer
1

Ved første øyekast ser det ut til at du bruker et ekstra nivå av pekeren indirekte, og som forårsaker segfault. Når du malloc minne, er det en peker til objektet, ikke en peker til en peker til et objekt. Så vil du ha:

img = (struct image *)malloc(sizeof(struct image))
img->o = 0
Svarte 24/02/2009 kl. 02:07
kilden bruker

stemmer
0

Oops, koden ble avskåret; Jeg glemte å unnslippe en mindre enn tegn. Her er det:

#include <stdio.h>
#include <stdlib.h>
struct color {
    unsigned char r, g, b;
};
struct image {
    int w, h/*, o*/;
    struct color **data;
};
int main() {
    // Declarations
    int x, y;
    struct color *black;
    struct image *img;
    // Set up color black
    black = (struct color *) malloc(sizeof(struct color *));
    black->r = 0;
    black->g = 0;
    black->b = 0;
    // Set up image img
    img = (struct image *) malloc(sizeof(struct image *));
    img->w = 1;
    img->h = 1;
    /*img->o = 0;*/
    img->data = (struct color **) malloc(img->h * sizeof(struct color *));
    for (y = 0; y < img->h; y++) {
        img->data[y] = (struct color *) malloc(img->w * sizeof(struct color));
    }
    // Fill in img with black
    for (x = 0; x < img->w; x++) {
        for (y = 0; y < img->h; y++) {
            img->data[y][x].r = black->r;
            img->data[y][x].g = black->g;
            img->data[y][x].b = black->b;
        }
    }
    // Free black
    free(black);
    // Free img
    for (y = 0; y < img->h; y++)
        free(img->data[y]);
    free(img->data);
    free(img);
    // Return
    return 0;
}
Svarte 24/02/2009 kl. 02:07
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more