3

我的程序中有一个小的内存访问问题,我没有找到错误,也许有人可以帮助我。

我创建了一种新类型来存储 rgb 颜色值。这种类型看起来像:

typedef struct pixel {
    unsigned char r;
    unsigned char g;
    unsigned char b;
} pixel;

在我的主程序中,我使用 calloc 创建了一个 2D 动态数组,以存储红色信息。

pixel **pixelvalue = (pixel **) calloc(imginformation.width, sizeof(pixel));
for (i = 0; i < imginformation.width; i++) {
    pixelvalue[i] = (pixel *) calloc(imginformation.height, sizeof(pixel));
}

之后我调用我的函数,它读取颜色值以及谁应该将它们保存到数组中。该函数将数组作为参数。

ReadFile(file, imginformation (Stuff like height and so one), pixelvalue (The calloc array));

在那个函数中,我尝试用

pixelvalue[i][j].r = (unsigned char)fgetc(in);

在这里我得到内存访问错误,我做错了什么?

编辑

嗨,首先对缺少的语言感到抱歉,我昨天有点累了:)。

为了理解,我创建了一个像素数组并且元素指向另一个像素数组?像[Point to another 1D array pixel]什么?

使用像素**pixelvalue = calloc(imginformation.width, sizeof(pixel *));,我从像素类型创建imginformation.width多个指针,每个指针都显示到像素,对吗?

如果我错了,如果您能再解释一下,那就太棒了。我真的很想了解它。

@carl-norum 你是什么意思:

“你不应该强制转换 calloc() 的返回值。这样做可以隐藏带有 #include 的错误,这些错误可能会回来咬你”。

? 我使用分配空间作为函数的参数,而不是返回值。

谢谢你的帮助!

格雷茨

4

4 回答 4

3

您实际上并不是在制作 2D 数组,而是在制作指向像素数组的指针数组。这意味着您的第一次calloc调用应该为指针分配足够的空间,而不是像素:

pixel **pixelvalue = calloc(imginformation.width, sizeof(pixel *));

您没有用语言标记您的问题,但假设它是 C(基于您的typedef,这在 C++ 中不是必需的),您不应该强制转换calloc(). 这样做可以隐藏#include可能会回来咬你的错误。

编辑:

你问了几个后续问题。我认为,第一个已经被其他几个答案很好地回答了,但我会尝试总结一下。按照您进行分配的方式,您首先要分配一个指针数组 - 每个指针都将指向数组的一行。然后需要分配行本身 - 每个pixel对象的空间都到那里,指向行的指针存储在第一个指针数组中。

你的第二个问题,关于返回值的问题calloc()非常简单。如果您强制转换返回值,您可以对自己隐藏隐式声明错误。由于返回类型callocvoid *,如果您执行以下操作:

my_ptr = calloc(1, 2);

一切都很好。现在假设您没有包含stdlib.h,因此calloc()在您的翻译单元中没有原型。这将导致编译器假定为的签名calloc()int calloc(int, int)这是不正确的。上面的同一行代码会给你一个关于假设该函数的默认签名的警告。使用代码中的类型转换将掩盖该警告,您可能永远不会知道您错过了该#include行。

于 2012-02-03T00:13:11.083 回答
1

请参阅图表以获取说明在此处输入图像描述

所以你首先创建了pixel *使用 calloc 的数组。calloc使用with填充该数组pixel

于 2012-02-03T09:12:46.807 回答
0

编码

pixel **pixelvalue = (pixel **) calloc(imginformation.width, sizeof(pixel)); 

pixelvalue是一个指向像素的指针——你的 typedef。

你需要写

pixel **pixelvalue = calloc(imginformation.width, sizeof(pixel *)); 

反而。

于 2012-02-03T08:33:16.683 回答
0

其他张贴者已正确确定您应该以 为单位分配您的第一个内存块,pixel*而不是以pixel.

但是为什么这个问题会导致段错误?

在 32 位机器上,上面定义的像素结构占用 3 个字节,但指针占用 32 位(4 个字节)。

那是,

  • sizeof(pixel) == 3
  • sizeof(pixel*) == 4

所以你只分配了你需要的 75% 的内存。访问图像的底部四分之一时,您将访问从未分配过的内存。

(在某些 64 位平台上,问题肯定只会变得更糟。在某些 16 位平台上,您也许可以侥幸逃脱,尽管它仍然很草率)

于 2012-02-03T09:27:24.407 回答