【问题标题】:Crash CGDataProviderCreateWithCopyOfData: vm_copy failed: status 1崩溃 CGDataProviderCreateWithCopyOfData:vm_copy 失败:状态 1
【发布时间】:2025-11-21 15:00:02
【问题描述】:

我正面临崩溃并出现以下错误:

“CGDataProviderCreateWithCopyOfData:vm_copy 失败:状态 1。”

我有很多问题,你可以帮忙。

  1. vm_copy failed 中的状态 1 代表什么?

  2. 仅当我在数据复制的内部 for 循环中设置断点时才会发生此崩溃。然后恢复并删除断点。如果没有断点,函数会执行但我得到一个空白图像。如何确保即使我没有设置断点,也能捕获此类崩溃并停止应用程序执行?

  3. 当我执行 CGBitmapContextCreateImage 时出现此错误。有谁知道如何解决这个问题?

-(UIImage *) convertBitmapRGBA8ToUIImage:(UInt8**)img 
                                    :(int) width
                                    :(int) height 
{

CGImageRef inImage = m_inFace.img.CGImage;

UInt8*piData = calloc( width*height*4,sizeof(UInt8));

int iStep,jStep;
for (int i = 0; i < height; i++) 
{
    iStep = i*width*4;
    for (int j = 0; j < width; j++) 
    {
        jStep = j*4;
        piData[iStep+jStep] =img[i][j];
        piData[iStep+jStep+1] =img[i][j];
        piData[iStep+jStep+2] = img[i][j];

    }
}

CGContextRef ctx = CGBitmapContextCreate(piData,
                                         CGImageGetWidth(inImage),  
                                         CGImageGetHeight(inImage),  
                                         CGImageGetBitsPerComponent(inImage),
                                         CGImageGetBytesPerRow(inImage),  
                                         CGImageGetColorSpace(inImage),  
                                         CGImageGetBitmapInfo(inImage) 
                                         ); 

CGImageRef imageRef = CGBitmapContextCreateImage(ctx);  
UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
CGContextRelease(ctx);
CGImageRelease(imageRef);
free(piData);
return finalImage;

}

【问题讨论】:

    标签: ios objective-c image crash cgbitmapcontextcreate


    【解决方案1】:

    kern_return.h 头文件给出:

    #define KERN_INVALID_ADDRESS        1
      /* Specified address is not currently valid.
       */
    

    这对应于vm_copy failed: status 1相关的错误码。

    我怀疑这是与内存对齐有关的问题,因为 vm_copy documentation 声明 address[es] 必须在页面边界上

    为确保您使用正确对齐的缓冲区,您应该以与 inImage 输入图像相同的步幅分配您的 piData 缓冲区:

    size_t bytesPerRow = CGImageGetBytesPerRow(inImage);
    UInt8*piData = calloc(bytesPerRow*height,sizeof(UInt8));
    

    然后在您的for 循环中使用这个bytesPerRow 值而不是width*4,即:

    iStep = i*bytesPerRow;
    

    这应该可以解决您的问题(注意:我假设CGImageGetWidth(inImage)width 是相同的)。

    【讨论】:

    • 是的,这是内存对齐问题。我没有考虑图像方向。这为 CGimage 提供了不同的宽度和高度。正如您所指出的,这导致内存未对齐。感谢您的回复。