C ++ memcpy和快乐访问冲突

时间:2011-07-27 15:27:00

标签: c++ access-violation memcpy

出于某种原因,我无法确定我是否会违反访问权限。

memcpy_s (buffer, bytes_per_line * height, image, bytes_per_line * height);

这是完整的功能:

int Flip_Bitmap(UCHAR *image, int bytes_per_line, int height)   
{   
    // this function is used to flip bottom-up .BMP images   

    UCHAR *buffer; // used to perform the image processing   
    int index;     // looping index   

    // allocate the temporary buffer   
    if (!(buffer = (UCHAR *) malloc (bytes_per_line * height)))   
        return(0);   

    // copy image to work area   
    //memcpy(buffer, image, bytes_per_line * height);   
    memcpy_s (buffer, bytes_per_line * height, image, bytes_per_line * height);

    // flip vertically   
    for (index = 0; index < height; index++)   
        memcpy(&image[((height - 1) - index) * bytes_per_line], &buffer[index * bytes_per_line], bytes_per_line);   

    // release the memory   
    free(buffer);   

    // return success   
    return(1);   

} // end Flip_Bitmap   

整码: http://pastebin.com/udRqgCfU

要运行它,您需要在源目录中使用24位位图。 这是一个更大的代码的一部分,我试图使Load_Bitmap_File函数工作... 那么,有什么想法吗?

3 个答案:

答案 0 :(得分:5)

您的访问权限受到侵犯,因为许多图片程序未正确设置biSizeImage 。您正在使用的图片可能将biSizeImage设置为0,因此您不会为图像数据分配任何内存(实际上,您可能会分配4-16个字节,因为即使请求的分配大小为0,大多数malloc实现也将返回非NULL值。因此,当您复制数据时,您将读取该数组的末尾,从而导致访问冲突。

忽略biSizeImage参数并自行计算图像大小。请记住,每条扫描线的大小必须是4个字节的倍数,因此您需要向上舍入:

// Pseudocode
#define ROUNDUP(value, power_of_2) (((value) + (power_of_2) - 1) & (~((power_of_2) - 1)))
bytes_per_line = ROUNDUP(width * bits_per_pixel/8, 4)
image_size = bytes_per_line * height;

然后只需使用相同的图像尺寸读取图像数据并翻转它。

答案 1 :(得分:3)

正如评论所说,图像数据不一定是width * height * bytes_per_pixel

存储器访问通常在32位边界上更快,并且在处理图像时速度通常很重要。因此,图像的行通常会移动到4字节(32位)边界

如果图像像素是32位(即RGBA),这不是问题,但如果你有每像素3字节(24位颜色),那么对于某些图像宽度,其中列数* 3不是4的倍数,然后在每行的edn处插入额外的空白字节。

图像格式可能有一个“步幅”宽度或elemsize值来告诉你。

答案 2 :(得分:2)

您为bitmap->bitmapinfoheader.biSizeImage分配image,但继续复制bitmap->bitmapinfoheader.biWidth * (bitmap->bitmapinfoheader.biBitCount / 8) * bitmap->bitmapinfoheader.biHeight个字节的数据。我打赌两个数字不一样。