下面代码中的第三行是否定义明确?
char* result = new char[0];
printf("%d\n", strlen(result));
printf("%s\n", result);
delete[] result;
当我运行代码时,我得到了预期的输出(长度为 0,后跟两个换行符)。但是,我不确定这是否是一种明确定义的行为,还是我只是走运。
三线调用是否明确?
最佳答案
简答:是未定义的行为
长答案:在 C++ 中,分配大小为 0
的数组将产生一个指向没有元素的数组的有效指针。
来自标准(取自 this answer ):
来自 5.3.4/7
When the value of the expression in a direct-new-declarator is zero, the allocation function is called to allocate an array with no elements.
来自 3.7.3.1/2
The effect of dereferencing a pointer returned as a request for zero size is undefined.
(强调我的)
这意味着无法正确读取(或写入)从 new T[0]
返回的指针请求。
两者都是 strlen
和 printf
对于字符串格式“%s
”,定义为适用于以特殊 NUL
结尾的字符串特点。他们需要从提供的指针中读取字符序列来尝试找到这个 NUL
字符以便正确操作(这会导致 UB,因为这需要取消引用指针)。这些行为在 C 标准中定义,因为 C++ 标准将大多数 C 库类型/函数的定义委托(delegate)回 C 标准。
printf
访问%s
被定义为执行以下操作:
来自 C11 标准 §7.21.6.1/6
If no l length modifier is present, the argument shall be a pointer to the initial element of an array of character type.
Characters from the array are written up to (but not including) the terminating null character. If the precision is specified, no more than that many bytes are written. If the precision is not specified or is greater than the size of the array, the array shall contain a null character.
这需要访问数组(这将是 UB,因为指针对于解引用无效)
奖金
由于使用了strlen
,您的示例代码实际上在第二行引入了UB。 ,出于与上述类似的原因。
strlen
被定义为执行以下操作:
来自 C11 标准 §7.24.6.3/3:strlen
功能
Returns
The strlen function returns the number of characters that precede the terminating null character.
这是 UB,原因与使用 printf
相同.
关于c++ - 使用 %s 调用 printf 并传递一个零长度的 char* 是未定义的行为吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51050366/