避免分配大小为零的内存空间
2.23 ID_zeroLengthAllocation
为了避免意料之外的错误,并提高可移植性,不应分配大小为零的内存空间。
当申请分配的内存空间大小为 0 时,malloc、calloc、realloc 等函数的行为是由实现定义的,可以分配元素个数为 0 的数组,也可以不进行任何分配,直接返回空指针。
在这种情况下,C++ 语言的 new 运算符会分配元素个数为 0 的数组,但这种数组往往没有实际价值,而且要注意元素个数为 0 的数组也需要被释放。
示例:
char* mkstr(size_t n) {
char* p = (char*)malloc(n * sizeof(char)); // ‘n’ may be zero
if (p != NULL) {
p[0] = '\0'; // May overflow
}
return p;
}
如果 malloc 的返回值不为空,并不能保证其分配的内存空间是可用的,如果不加判断就直接访问会导致缓冲区溢出等问题。
应改为:
char* mkstr(size_t n) {
char* p = NULL;
if (n != 0) {
p = (char*)malloc(n * sizeof(char));
if (p != NULL) {
p[0] = '\0'; // OK
}
}
return p;
}
又如:
int* p = (int*)malloc(n * sizeof(int));
....
realloc(p, 0); // Non-compliant, use free(p) instead
C90 规定当 realloc 函数的长度参数为 0 时会释放内存,与 free(p) 相同,但在后续标准中废弃了这一特性,不应继续使用。
相关
依据
ISO/IEC 9899:1990 7.10.3.4
ISO/IEC 9899:1999 7.20.3(1)-implementation
ISO/IEC 9899:2011 7.22.3(1)-implementation
ISO/IEC 14882:2003 5.3.4(7)
ISO/IEC 14882:2011 5.3.4(7)