使用宏或用户定义函数检查malloc的返回值



通过两种方式检查malloc返回值的有效方法:

  1. 使用宏

    #define ALLOC(p,n) do{ *p=malloc(n*sizeof **p); } while(0)
    
  2. 用户定义功能

    static inline void *MallocOrDie(size_t MemSize)
    {
    void *AllocMem = malloc(MemSize);
    /* Some implementations return null on a 0 length alloc,
    * we may as well allow this as it increases compatibility
    * with very few side effects */
    if(!AllocMem && MemSize)
    {
    printf("Could not allocate memory!");
    exit(-1);
    }
    return AllocMem;
    }
    

在不同的情况下,这更有效。

注意:不想使用calloc而不是malloc,因为不想更改API的

由于您不想更改API,请考虑使用new[]delete[]这两种更简单的方法。如果您没有安装异常处理程序,如果new失败,将立即调用std::terminate,因此您不需要手动检查。

#define ALLOC(p,n) *(p) = MallocOrDie((n) * sizeof *(p))
static inline void* MallocOrDie(size_t MemSize) {
return new char[MemSize];
}
static inline void Free(void* p) {
delete [] static_cast<char*>(p);
}

或者作为宏的替代:

template<class T>
void ALLOC(T*& p, size_t n) { p = new T[n]; }
template<class T>
void FREE(T* p) { delete[] p; }

然而,这不是应该做的。为多个元素而不是bytes分配空间。如果您需要10int的空间,但不喜欢零初始化它们的额外成本,请使用std::make_unique_for_overwrite:

auto array = std::make_unique_for_overwrite<int[]>(10);

这会更改API(它应该更改(,因为您现在得到的是std::unique_ptr<int[]>而不是void*,但它的好处是,当array超出范围时,它将自动被delete[]编辑,因此需要担心的问题会减少很多。你也可以直接索引这个智能指针,而不需要强制转换,所以

{
auto array = std::make_unique_for_overwrite<int[]>(10);
array[9] = 123;
}

而不是

{
int* array = static_cast<int*>(MallocOrDie(10 * sizeof *array));
array[9] = 123;
Free(array);
}

但是,我建议您使用std::vector。它只需要零初始化而不是默认初始化,但除非你注意到有问题,否则不要放弃这个想法。通过按值(复制它们(而不是按引用来传递(这至少和四处传递指针一样便宜(,很容易滥用std::vector,这使得新的C++程序员不愿意使用它们。只要学会它们,编程生活就会轻松很多。

std::vector<int> array(10);

相关内容

  • 没有找到相关文章

最新更新