简体   繁体   中英

Getting memory addresses from array for only some values in C

I hate to dump code like I'm about to, but this has really baffled me. I am making a program to read PPM image files, which are files with a format, a comment, a width and height, and a maximum colour value.

Then after that there is a sequence of RGB values seperated by spaces, I have created a struct to hold three ints to represent an RGB colour, and a struct to hold all of the info about the PPM file and the array of pixels, which is an array of colour pointers.

typedef struct colour {
    int r,g,b;
} colour;

typedef struct ppm {
    char * format;
    int width, height, max;
    colour * pixels[];
} ppm;

And an initialiser to create a new colour triple:

colour * new_colour(int r, int g, int b) {
    colour * c = (colour *)malloc(sizeof(colour));
    c->r = r;
    c->g = g;
    c->b = b;
    return c;
}

I then have a method that reads a PPM file to create a ppm struct:

ppm * get_ppm(FILE * ppm_file){
    ppm * my_ppm = malloc(sizeof(ppm));
    char format[20];
    char comment[100];
    int n, m, max;

    fgets(format, 10, ppm_file);
    fgets(comment, 100, ppm_file);

    char dimension_line[100];
    fgets(dimension_line, 100, ppm_file);
    sscanf(dimension_line,"%d %d", &n, &m);

    char max_line[20];
    fgets(max_line, 20, ppm_file);
    sscanf(max_line, "%d", &max);

    int i;  
    for (i = 0; i<=(m*n - 1); i++) {
        my_ppm->pixels[i] = malloc(sizeof(colour));
        int r, g, b;
        fscanf(ppm_file,"%d %d %d ",&r,&g,&b);
        my_ppm->pixels[i] = new_colour(r,g,b);
    }

    my_ppm->format = format;
    my_ppm->width = n;
    my_ppm->height = m;
    my_ppm->max = max;
    return my_ppm;
} 

And then I have a method to print my ppm file:

void show_ppm(ppm * image) {
    printf("Format: %s\nW:%d H:%d\nMAX:%d\n\n", image->format, 
                                                image->width, image-> height,
                                                image->max);
    int i;
    for (i = 0; i<=(image->height)*(image->width) - 1; i++) { 
        int r = image->pixels[i]->r;
        int g = image->pixels[i]->g;
        int b = image->pixels[i]->b;
        printf("p[%d]: (%d,%d,%d)\n",i,r,g,b);
    }
}

The image I'm using is this:

P3
# feep.ppma
4 4
15
 0  0  0  0  0  0    0  0  0   15  0 15
 0  0  0  0 15  7    0  0  0    0  0  0
 0  0  0  0  0  0    0 15  7    0  0  0
15  0 15  0  0  0    0  0  0    0  0  0

It reads in perfectly fine, I've done some printf debugging and it's always the right values, even when I save the values in the struct it's fine, but when I run show_ppm, I get what I assume are memory addresses for the first two values?

p[0]: (26928080,0,26928144)
p[1]: (26928592,0,26928656)
p[2]: (0,0,0)
p[3]: (15,0,15)
p[4]: (0,0,0)
p[5]: (0,15,7)
p[6]: (0,0,0)
p[7]: (0,0,0)
p[8]: (0,0,0)
p[9]: (0,0,0)
p[10]: (0,15,7)
p[11]: (0,0,0)
p[12]: (15,0,15)
p[13]: (0,0,0)
p[14]: (0,0,0)
p[15]: (0,0,0)

However everything else is fine? I've got no clue what I'm doing wrong here, pls help me

If you want to look at the entire file here it is: http://pastebin.com/1FrMBYAS

Thanks in advance, Ciaran

The declaration colour * pixels[] does not actually reserve any space for that array. When you put something like this at the end of a structure, you need to allocate space for the array beyond the size of the structure itself to hold the elements of the array. For example, if you have 100 pixels, your allocation should look like this:

ppm *my_ppm = malloc(sizeof(ppm) + 100*sizeof(colour *));

If you don't know the number of pixels beforehand, you can allocate space for an initial amount and then realloc if you need more space.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM