C++中向char数组末尾后一位写入'\0'是否会引发未定义行为?
C++ 字符串边界写入合法性分析
前置问题解答
- 手动向字符串字面量末尾的
'\0'位置写入是完全不安全的,该操作属于未定义行为。 - NULL字符(
'\0')不会默认出现在任意数组末尾的下一个内存位置,只有字符串字面量会在编译时自动追加一个'\0'作为自身的一部分,普通char数组不存在该默认机制。
代码片段逐一分析
你给出的三段代码具体行为如下:
const char* a = "Hello"; a[5] = '\0'; //this is wrong, will not compile on most compilers char* b = new char[5]; b[5] = '\0'; char c[5]; c[5] = '\0';
- 第一段代码:
a指向的是存储在只读内存段的字符串字面量,const修饰指向内容不可修改,因此直接写入会直接编译报错。即使通过const_cast强制去除const属性进行写入,也会触发段错误,属于典型的未定义行为。补充说明:这里的"Hello"实际占用6个char的存储空间,下标5对应的是编译器自动追加的'\0',但该位置属于只读内存,本身就不支持写入操作。 - 第二段代码:
new char[5]申请了长度为5的堆上char数组,合法可访问的下标范围是0~4,b[5]属于堆缓冲区越界写入,属于未定义行为,可能破坏堆上其他有效数据,引发程序崩溃或安全漏洞。 - 第三段代码:
c是栈上分配的长度为5的char数组,合法下标同样是0~4,c[5]属于栈缓冲区越界写入,属于未定义行为,可能覆写栈上的函数返回地址、其他局部变量等,导致程序逻辑异常甚至被恶意利用。
补充:如果你需要存储长度为5的字符串并追加末尾
'\0',需要申请长度至少为6的char数组,此时对下标5的写入才是合法操作。
内容的提问来源于stack exchange,提问作者CuriousPan
相关产品推荐
相关产品推荐

