Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用此功能复制二维图像数据-为什么工作?_C_Image - Fatal编程技术网

C 使用此功能复制二维图像数据-为什么工作?

C 使用此功能复制二维图像数据-为什么工作?,c,image,C,Image,下面的代码将2d数据从src复制到dst,在下面的测试中没有明显的“问题”,但我知道代码是错误的,并且还提供了正确的代码。在这里,我要问的是到底哪里出了问题我的解释是指针本身是一个多字节变量,如果指针值(无符号字符)的大小与指针的大小不同,则取消对双指针的引用会遇到问题。您认为如何 我必须指出,强制转换“unsigned char**”不会改变底层数据,因此,如果代码被修改为使用另一个本地间接寻址,那么实际上一切工作都很完美,请参见下面的内容: void copy_2d_data(unsigne

下面的代码将2d数据从src复制到dst,在下面的测试中没有明显的“问题”,但我知道代码是错误的,并且还提供了正确的代码。在这里,我要问的是到底哪里出了问题我的解释是指针本身是一个多字节变量,如果指针值(无符号字符)的大小与指针的大小不同,则取消对双指针的引用会遇到问题。您认为如何

我必须指出,强制转换“unsigned char**”不会改变底层数据,因此,如果代码被修改为使用另一个本地间接寻址,那么实际上一切工作都很完美,请参见下面的内容:

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和 DY-IMG如何定义和初始化?它是因为“未定义的行为”和“事物”而“工作”的。但是,这个程序中没有任何远程正确的内容。这就像问“我吃了泥,但我仍然感觉很好,这是为什么?”问题和答案似乎是c,因此我删除了另一个标记“下面的代码将2d数据从src复制到dst,没有问题”。不,这里并不是这样。下面是另一个描述:“通过随机添加强制类型转换和操纵循环边界,我强制一个测试在我的机器上通过”。这听起来更真实吗?如果您需要在函数调用期间强制转换指针,那么您的某个地方有一个bug。而且,“管理阵列”是非常过时的C99之前的样式。
    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);