【问题标题】:Occasional unexpected output when accessing data from multidimensional array in C从 C 中的多维数组访问数据时偶尔出现意外输出
【发布时间】:2021-10-24 04:43:59
【问题描述】:

我有一段代码将图像中的字节存储到存储在结构中的多维数组中。在将字节分配给数组时,预期数据(0xFF,因为我正在使用纯白色图像进行测试)和 pixel_array[i][j][k] 处的数组实际指向的数据都匹配。这是在数组中存储数据的代码的 sn-p:

unsigned char pixel[bmp_image->pixel_width];
bmp_image->pixel_array = malloc(bmp_image->width * sizeof(unsigned char));

for (int i = 0; i < bmp_image->width; i++) {
    bmp_image->pixel_array[i] = malloc(bmp_image->height * sizeof(unsigned char));

    for (int j = 0; j < bmp_image->height; j++) {
        bmp_image->pixel_array[i][j] = malloc(bmp_image->pixel_width * sizeof(unsigned char));
        fread(pixel, sizeof(pixel), 1, bmp_data);

        // Pixel width refers to the size of a pixel in bytes
        for (int k = 0; k < bmp_image->pixel_width; k++) {
            bmp_image->pixel_array[i][j][k] = pixel[k];
            // These two print statements always result in the same data (i.e. both print 0xFF for the white test image)
            printf("Expected byte: %x\n", pixel[k]);
            printf("Saved byte: %x\n\n", bmp_image->pixel_array[i][j][k]);
        }
    }

    fseek(bmp_data, padding, SEEK_CUR);
}

这是存储图像数据的结构:

struct Image {
    FILE *image_file;
    int width;
    int height;
    int pixel_width;
    int error_code;
    unsigned char*** pixel_array;
};

我的问题是,一旦我尝试使用以下代码访问存储在像素数组中的字符,我就会得到随机的意外输出(即不是十六进制 FF)

for (int i = 0; i < bmp_image->width; i++) {
    for (int j = 0; j < bmp_image->height; j++) {
        for (int k = 0; k < bmp_image->pixel_width; k++) {
            printf("%x", bmp_image->pixel_array[i][j][k]);
        }
    }
}

下面是一个 10x10 白色图像的输出示例(预计只有 ff):

6050a3c051a32053a38054a3e055a34057a3ffffffffffffffffffffffffc04ca3404da3fffffffffffffffffffffffff
fffffffffffffffffffffff204ea3a04ea3ffffffffffffffffffffffffffffffffffffffffffffffff804fa3050a3fff
fffffffffffffffffffffffffffffffffffffffffffffe050a36051a3ffffffffffffffffffffffffffffffffffffffff
ffffffff4052a3c052a3ffffffffffffffffffffffffffffffffffffffffffffffffa053a32054a3fffffffffffffffff
fffffffffffffffffffffffffffffff055a38055a3ffffffffffffffffffffffffffffffffffffffffffffffff6056a3e
056a3ffffffffffffffffffffffffffffffffffffffffffffffffc057a34058a3ffffffffffffffffffffffffffffffff
ffffffffffffffff

随机数据似乎总是在同一个位置,但值每次都不同。我假设我遇到了一些错误分配指针的问题,但到目前为止,我对可能导致它的原因感到困惑。

【问题讨论】:

  • 代码不完整。比如pixel_array是怎么分配的?寻求调试帮助的问题必须提供complete minimal reproducible example。请使用任何人都可以完全按照所示重现问题的代码更新问题。
  • malloc(bmp_image-&gt;height * sizeof(unsigned char) 应该使用sizeof(unsigned char*)
  • 更安全的是sizeof *bmp_image-&gt;pixel_array[i]。如果您只是复制要分配的变量并在其前面加上*,则无论其类型是什么,大小都将始终正确。
  • unsigned char*** pixel_array;
  • 嗯:黄金法则是:如果您只需要两颗星,您可能需要某种结构。或不同的数据模型。 [任何规则都有例外]

标签: c malloc stdio


【解决方案1】:

看来您分配的内存不足。

bmp_image->pixel_array[i] = malloc(bmp_image->height * sizeof(unsigned char));

它为bmp_image-&gt;height 分配内存,而它应该为bmp_image-&gt;height 指针 分配资源。有助于避免此类错误的良好模式是:

x = malloc(sizeof *x);

对于这种情况,它将是:

bmp_image->pixel_array[i] = malloc(bmp_image->height * sizeof(*bmp_image->pixel_array[i]));

我假设bmp_image-&gt;pixel_array 在使用前已正确分配。

【讨论】:

  • 这非常有效,谢谢!因此,为了确保我理解这一点,c 中的数组在技术上存储指向内存中该索引处的值的指针?因此,由于 char 类型通常比指针小,这就是为什么没有分配足够的内存而我正在访问随机未分配的垃圾值?
  • @Ethan Peck,它有点复杂。您可以在 stackoverflow.com/a/918121/4989451 以及该线程的其他答案中找到非常详细的解释。
猜你喜欢
  • 2012-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-24
  • 1970-01-01
  • 2021-08-09
相关资源
最近更新 更多