在C中创建2D数组时检查malloc失败

velaa5lx  于 2023-03-22  发布在  其他
关注(0)|答案(1)|浏览(93)

我试图检查在创建2D数组时是否错误定位失败。这是我想到的:

...
image->imageData = (unsigned int**) malloc(image->height * sizeof(unsigned int*));
// if malloc is unsuccessful, it will return a null pointer
if (image->imageData == NULL) { // check malloc
  image->errorStatus = BAD_MALLOC;
  return image;
} // check malloc

for(int nRow = 0; nRow < image->height; nRow++) {
  image->imageData[nRow] = (unsigned int*) malloc(image->width * sizeof(unsigned int));
  // if malloc is unsuccessful, it will return a null pointer
  if (image->imageData[nRow] == NULL) { // check malloc
    image->errorStatus = BAD_MALLOC;
    return image;
  } // check malloc
}
...

malloc失败的情况是如果图像尺寸太大(image-〉height和image-〉width)导致程序耗尽内存。我知道这个代码片段不能检测到它,因为当我复制这个情况时,image-〉errorStatus被设置为其他值(在程序的更下面)。我的问题是为什么这个代码片段不能检测到malloc失败。

xxhby3vn

xxhby3vn1#

如果一行分配失败,则应该释放到目前为止分配的内存并返回NULL。如果分配了image,则应该释放它并返回NULL

struct Image *alloc_iamge(int heigth, int width) {
    struct Image *image = calloc(1, sizeof(*image));
    if (image == NULL)
        return NULL;
    image->height = height;
    image->width = width;
    image->imageData = malloc(image->height * sizeof(unsigned int*));
    // if malloc is unsuccessful, it will return a null pointer
    if (image->imageData == NULL) { // check malloc
        free(image);
        return NULL;
    }

    for (int nRow = 0; nRow < image->height; nRow++) {
        image->imageData[nRow] = calloc(image->width, sizeof(unsigned int));
        // if malloc is unsuccessful, it will return a null pointer
        if (image->imageData[nRow] == NULL) {
            while (nRow > 0) {
                free(image->imageData[--nRow]);
                image->imageData[nRow] = NULL;
            }
            free(image->imageData)
            image->imageData = NULL;
            free(image);
            return NULL;
        }
    }
    return image;
}

如果内存分配失败,malloccalloc将返回NULL。在现代操作系统上,如果分配大小超过进程可用的配额,就会发生这种情况。如果malloc成功,内存可能被访问,但可能还不可用:存储器可能被过度使用,即:页面将在稍后被写入时被Map到进程地址空间,并且相同或另一进程的一些其它页面将根据需要被回收。代码页面和文件缓存页面将仅被重用,并且数据页面将被写入交换文件以供稍后重新加载。其它存储器管理技术可用于优化存储器使用,诸如在存储器压缩中(例如:macOS)的操作系统。

相关问题