【问题标题】:Getting memory addresses from array for only some values in C从数组中仅获取 C 中某些值的内存地址
【发布时间】:2017-02-22 16:34:30
【问题描述】:

我讨厌转储代码,但这确实让我感到困惑。 我正在编写一个程序来读取 PPM 图像文件,这些文件具有格式、注释、宽度和高度以及最大颜色值。

然后,有一个由空格分隔的 RGB 值序列,我创建了一个结构来保存三个整数来表示 RGB 颜色,以及一个结构来保存有关 PPM 文件和像素数组的所有信息,这是一个颜色指针数组。

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

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

还有一个用于创建新颜色三元组的初始化程序:

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

然后我有一个读取 PPM 文件以创建 ppm 结构的方法:

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

然后我有一个方法来打印我的 ppm 文件:

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

我使用的图片是这样的:

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

它读起来非常好,我已经进行了一些 printf 调试,它始终是正确的值,即使我将值保存在结构中也很好,但是当我运行 show_ppm 时,我得到了我认为的内存地址前两个值?

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)

但是其他一切都很好吗?我不知道我在这里做错了什么,请帮助我

如果你想在这里查看整个文件,它是: http://pastebin.com/1FrMBYAS

提前致谢,夏兰

【问题讨论】:

  • 旁白:i &lt;= n-1 的代码比简单的i &lt; n 更难阅读。
  • 您没有为pixels 分配任何空间。当您mallocmy_ppm 时,您需要将像素数组的大小添加到sizeof(ppm)。声明 colour * pixels[] 实际上并没有为该数组保留任何空间。
  • @user2930356:是的,new_colour 为像素分配内存,但您还没有为colour 内的colour 指针数组分配内存@。在为my_ppm 分配内存时,您需要考虑该数组所需的内存。例如,如果您有 100 个像素,您应该这样做:ppm *my_ppm = malloc(sizeof(ppm) + 100*sizeof(colour *));
  • @user2930356:你确定你真的想要一个颜色指针数组而不是颜色数组吗?是的,您必须修改 new_colour() 函数,但如果您存储一组颜色,您会更节省空间。您可能应该推迟为结构分配空间,直到您知道需要多少空间。

标签: c arrays pointers struct


【解决方案1】:

声明colour * pixels[] 实际上并没有为该数组保留任何空间。当你把这样的东西放在结构的末尾时,你需要为数组分配超出结构本身大小的空间来保存数组的元素。例如,如果您有 100 个像素,您的分配应如下所示:

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

如果您事先不知道像素数,您可以分配初始数量的空间,如果需要更多空间,则可以分配realloc

【讨论】:

  • 或者干脆推迟结构的分配,直到尺寸线被读取,这样你就知道要分配多少空间。
  • 鉴于这种分配方法,您可能还应该展示如何初始化ppm-&gt;pixels,之后...
  • @Bob__:你不需要初始化pixels。你只需要知道有多少像素。
  • 好吧,现在您已经分配了足够的内存来存储(连续)struct ppm 和 100 个指向struct colour指针。您仍然必须为ppm-&gt;pixels 指针分配一个值,最重要的是为所有struct colours 分配内存。我认为,正如 Jonathan Leffer 所建议的那样,存储一组颜色可能会更好。
  • pixels的声明方式(如colour *pixels[]),你可以在做malloc之后直接使用。无需单独操作即可将pixels 设置为某事。我同意让它成为一个colour 的数组比让它成为一个指针数组更有意义。
猜你喜欢
  • 2020-03-14
  • 1970-01-01
  • 1970-01-01
  • 2012-07-05
  • 1970-01-01
  • 2012-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多