C 使用此功能复制二维图像数据-为什么工作?
下面的代码将2d数据从src复制到dst,在下面的测试中没有明显的“问题”,但我知道代码是错误的,并且还提供了正确的代码。在这里,我要问的是到底哪里出了问题我的解释是指针本身是一个多字节变量,如果指针值(无符号字符)的大小与指针的大小不同,则取消对双指针的引用会遇到问题。您认为如何 我必须指出,强制转换“unsigned char**”不会改变底层数据,因此,如果代码被修改为使用另一个本地间接寻址,那么实际上一切工作都很完美,请参见下面的内容:C 使用此功能复制二维图像数据-为什么工作?,c,image,C,Image,下面的代码将2d数据从src复制到dst,在下面的测试中没有明显的“问题”,但我知道代码是错误的,并且还提供了正确的代码。在这里,我要问的是到底哪里出了问题我的解释是指针本身是一个多字节变量,如果指针值(无符号字符)的大小与指针的大小不同,则取消对双指针的引用会遇到问题。您认为如何 我必须指出,强制转换“unsigned char**”不会改变底层数据,因此,如果代码被修改为使用另一个本地间接寻址,那么实际上一切工作都很完美,请参见下面的内容: void copy_2d_data(unsigne
void copy_2d_data(unsigned char **dst, unsigned char **src, int w, int h)
{
printf("copy_2d_data img width = %d, height = %d\n ......\n", w, h);
// wrong code:
for (int row=0; row<w-2; row++) { //note here -> w-2
for (int col=0; col<h-2; col++) { //note here -> h-2
//**dst++ = **src++; //this will cause seg fault, so don't try it
*dst++ = *src++;
}
}
#if 0 // the correct code starts:
unsigned char *s = (unsigned char *)src;
unsigned char *d = (unsigned char *)dst;
for (int row=0; row<w; row++) {
for (int col=0; col<h; col++) {
*d++ = *s++;
}
}
#endif
printf("copy_2d_data done\n");
}
你怀疑这段代码是对的,因为它错得很有趣 如果要复制二维数组
char
,则需要复制w
×h
字节。接受两个char*
指针或两个void*
指针的函数可以工作。(为了完整性,下面的示例。)值得注意的是,对memcpy
的简单调用也同样有效,因为复制连续字节正是memcpy
所做的
但是这个copy\u 2d\u data
函数不复制字节。它复制void*
指针。根据您使用的机器的不同,void*
指针可能是32位或64位,也可能是4或8字节。所以这个函数应该一次复制1个字节,实际上是一次复制4或8个字节。因此,我预计它会严重溢出目标数组
但是!它的循环不运行w
×h
次。由于某些无法解释的原因,它运行(w
-2)×次(h
-2)。有时,至少,这两个近乎随机的减法将安排函数不过度复制太多。(有时,它们意味着函数的复制量不够。有时,它们甚至可能恰好达到恰到好处的复制量。)
似乎有人错误地认为二维数组包含两级指针。(这是错误的,但这是一个常见且相当明显的错误。)当函数不起作用时,有人可能会发现它复制了太多,并想到了一些想象中的原因,为什么从维度中减去2是一个合理的修正。(显然不是。)
这将有助于:
void copy_2d_data(unsigned char *dst, unsigned char *src, int w, int h)
{
for (int row=0; row<w; row++) {
for (int col=0; col<h; col++) {
*dst++ = *src++;
}
}
}
完成后,它就相当于memcpy
,您可以调用它:
memcpy( d_img, s_img, w * h );
对于5×5示例,您希望复制25个字节,而不是复制3×3×4=36个字节或3×3×8=72个字节。还是太多了。我很惊讶它能工作,但我在我的机器上试过,在那里我更惊讶它能工作!(我知道我的机器有64位指针,72明显比25大!) 为了让自己相信正在发生的事情,这里有两件事你可以尝试
copy_2d_data
后,尝试打印出源阵列和目标阵列。您可能会发现(我确实发现)源数组已被更改,这无疑是因为过度复制s_img
和d_img
的声明:首先声明d_img
,然后声明s_img
。您可能会发现(我确实发现)程序崩溃,因为过度复制会覆盖更重要的内容最后,您显然需要重新考虑复制图像阵列的方式。它不起作用,或者(目前)由于运气不好,它似乎起作用 指向指针的指针与二维数组无关,也不能指向二维数组。在处理指针数组时,可以使用指针对指针,但这里不是这样。这就是为什么在
copy\u 2d\u data
调用期间,如果不添加不正确的强制转换,就无法编译此代码的原因
您可以将函数更改为:
void copy_2d_data (int row, int col, unsigned char dst[row][col], unsigned char src[row][col])
{
printf("copy_2d_data img width = %d, height = %d\n ......\n", w, h);
for (int r=0; r<row-2; r++) {
for (int c=0; c<col-2; c++) {
dst[row][col]
}
}
printf("copy_2d_data done\n");
}
代码看起来像C代码。你真的使用C++编译器吗?<代码> SyIMG和
void copy_2d_data(unsigned char *dst, unsigned char *src, int w, int h)
{
for (int i=0; i<w*h; i++) {
*dst++ = *src++;
}
}
void copy_byte_array(unsigned char *dst, unsigned char *src, int n)
{
for (int i=0; i<n; i++) {
*dst++ = *src++;
}
}
copy_byte_array( (unsigned char *)d_img, (unsigned char *)s_img, w * h );
memcpy( d_img, s_img, w * h );
void copy_2d_data (int row, int col, unsigned char dst[row][col], unsigned char src[row][col])
{
printf("copy_2d_data img width = %d, height = %d\n ......\n", w, h);
for (int r=0; r<row-2; r++) {
for (int c=0; c<col-2; c++) {
dst[row][col]
}
}
printf("copy_2d_data done\n");
}
copy_2d_data(w, h, d_img, s_img);