将 union 中的 struct 修改为 union 中的其他值而不复制

Modify struct in union to other value in union without copy

我有这个结构:

typedef struct sPixelRGB {
    int r;
    int g;
    int b;
} sPixel;

typedef struct tsImagePPM {
    long imax;
    sPixel ** array;
} sImagePPM;

typedef struct tsImagePGM {
    long imax;
    int ** grey;   
} sImagePGM;

union imgType{
   sImagePPM imgP;
   sImagePGM imgG;
 };

typedef struct sImage{
   union imgType sImg;
   long height;
   long width;
   int type;
}img;

它表示 PPM (rgb) 或 PGM(仅灰色)图像 (https://en.wikipedia.org/wiki/Netpbm_format)。

我必须通过以下简单的公式将我的图片(原本是 PPM)转换为 PGM:

grey = 0.299 × r + 0.587 × g + 0.114 × b

我想将此结构与联合一起使用,因为我必须执行其他功能。我想知道是否可以将 sImg.imgP 修改为 sImg.imG 而无需制作新的 sImagePPM,用新的灰度值填充它,然后将其影响到并集。

更一般地说,我想知道是否可以这样做:

//img imgPM is initialize
imgPM.sImg.imgG.imax = imgPM.sImg.imgP.imax 
for (i = 0 ; i < width ;  i++){
    for (j = 0 ; j < height ;  j++){
        imgPM.sImg.imgG[i][j] = imgPM.sImg.imgP[i][j]

因为,当我从文件中读取我的图像时,我没有看到我在读取 PGM 图像时忘记将 imgP 更改为 imgG,并且显示 PGM 结构的 imax 是可能的,即使如果我在联合中初始化了一个 PGM 结构。

我不确定它在内存方面是如何工作的,尽管我读了很多关于它的东西。

结构的 imax 成员应该可以访问。如果联合包含 sImagePPM,当您尝试访问 imG 成员时,sImagePPM 的表示将被重新解释为 sImagePGM 结构的表示。该结构的第一个成员具有该结构的地址,因此 imP 成员表示的第一个字节将是 imP.imax.

的表示

因为具有相同表示的两个数字应具有相同的值 imgPM.sImg.imgG.imax 应具有 imgPM.sImg.imgP.imax had.

的值

指针的情况可能会更糟,因为 sPixelint 是不同的类型,指针和指向它们的指针也是如此。

只有在sPixels的所有数组和指向它们的指针数组都是动态分配的情况下,才能重用内存,因为动态内存没有声明类型,它接收的是写在那里的数据。但在那种情况下,为 int **int * 数组分配一个新的内存块,计算 sPixel array 中所有像素的值,然后影响新计算的数组会更简单imgPM.sImg.imgG.grey 成员和 sPixel 数组使用的空闲内存。