c++内存和愉快访问冲突

C++ memcpy and happy access violation

本文关键字:访问冲突 内存 c++      更新时间:2023-10-16

由于某些原因,我无法确定我正在获得访问冲突。

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函数工作…有什么想法吗?

您将获得访问冲突,因为许多图像程序没有正确设置biSizeImage 。你正在使用的图像可能有biSizeImage设置为0,所以你没有为图像数据分配任何内存(在现实中,你可能分配4-16字节,因为大多数malloc实现将返回一个非NULL值,即使请求的分配大小为0)。所以,当你去复制数据时,你正在读取该数组的末尾,这导致访问冲突。

忽略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;

然后使用相同的图像大小读取图像数据和翻转它

正如注释所说,图像数据不一定是宽度*高度*bytes_per_pixel

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

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

图像格式可能有一个"stride"宽度或elemsize值来告诉你这些

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