为什么我的编译器不阻止我向0地址写入?

发布时间:
2024-05-07 22:06
阅读量:
8

注意啊,给一些同学打预防针,nullptr 已经进 C 标准了(C23)。(另外,这又是 C 和 C++ 不同的一点,nullptr_t 到 bool 的转换(nullptr 会转为 false)在 C 中被认为是隐式转换,而在 C++ 不认为是隐式转换。)


根据 C 标准,malloc 不成功时会返回 nullptr。Dereferencing a nullptr 当然是非法的。这题假设循环中不断分配内存而不释放,最后系统资源不足导致 malloc 返回 nullptr。

但现实情况是,系统会用虚拟内存,而你的程序需要访问磁盘在很慢地运行,而其他程序接着跑罢了,直到耗完虚拟内存的配额才会返回 nullptr。但这很难发生,不单是要读写磁盘,而且随着堆上增加了巨量微小对象(一般而言,64 位系统上分配 1 字节空间实际会占用 16 到 24 字节内存),堆本身的性能也在下降。Malloc 每次分配耗时都会越来越长。要耗完整个几百 GB 的空间(虚拟内存大小的一种可能情形)可能需要十几分钟甚至是几小时。


所以说,malloc 的结果都应该检查 nullptr。而 C++ 就该用异常,合适的场合捕获 std::bad_alloc。

END