如何解决将 uint16_t 转换为 unsigned int
我们已经投射了二维数组:
struct pixel(*image_data)[width] = (struct pixel(*)[width])img->px;
- 我不明白它是如何转换和分配内存的?
其中宽度:
unsigned width = img->size_x;
和结构图像:
struct image {
uint16_t size_x;
uint16_t size_y;
struct pixel *px;
};
第二个问题:
宽度可以容纳的最大值是多少?
第三:
如果我们迭代 image_data[x][y] 其中 x 和 y 很长,那么会出现缓冲区溢出吗?
解决方法
-
演员表不分配内存。
image_data
变量的类型是“指向width
的长度为struct pixel
的数组的指针”(使用width
声明点处的image_data
),所以image_data + i
是指向i
的第struct pixel
行(从 0 开始计数)的指针。 -
理论上,
width
可以是不超过SIZE_MAX / sizeof (struct pixel)
的任何值,但可能会受到其他约束的限制。此外,size_x
中的size_y
和struct image
受其类型uint16_t
的限制为最大值 65535。 -
如果
x >= 0
和y >= 0
和y < width
(其中width
仍然具有值sizeof (*image_data) / sizeof ((*image_data)[0])
)以及 {{1} 指向的缓冲区}} 至少为img->px
字节长(并正确对齐sizeof (struct pixel) * (x + 1) * width
),则不会出现缓冲区溢出。
关于 struct pixel
变量的定义:
width
unsigned width = img->size_x;
的类型为 img->size_x
,uint16_t
的最大值正好 65535。uint16_t
的类型为 width
,并且unsigned int
的最大值至少为 65535,因此 unsigned int
将被初始化为 width
的值而不会被截断。
在对该问题的评论中,Lundin 提到 img->size_x
与 struct Pixel *
不兼容。确实如此,但 C 允许从一种指针类型转换为另一种指针类型。如果结果指针未针对引用类型正确对齐(此处引用类型为 struct pixel(*)[width]
),则行为未定义。数组类型比相应的元素类型具有更严格的对齐要求是非常不寻常的,所以这可能是可以的。即使数组类型有比元素类型更严格的对齐要求,只要指针实际上正确对齐就可以了。如果 struct pixel [width]
指向由 img->px
、malloc
或类似物分配的块,那么它对于具有“基本”对齐的任何对象类型都正确对齐,因此没问题。主要问题是,如果像素数据同时通过 calloc
和 img->px
访问,那么这将违反严格别名规则,因为指针具有不兼容的类型。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。