一个空C风格字符串通过指针赋值后,为什么strlen()还是0?

#include <iostream>
#include <cstring>

using namespace std;

int main(int argc, char *argv[])
{
	char cc[] = "";
	cc[0] = 'a';
	cc[1] = 'b';
	cc[2] = '\0';
	cout << strlen(cc) << endl;
	return 0;
}

看大家都说是越界的问题,我试过了不是的,因为下面这种情况越界也是可以strlen()的

#include <iostream>
#include <cstring>

using namespace std;

int main(int argc, char *argv[])
{
	char cc[] = "a";
	cc[1] = 'a';
	cc[2] = 'a';
	cc[3] = '\0';
	cout << strlen(cc) << endl;
	return 0;
}

 

程序数组访问越界了

不过这似乎是gcc优化的结果,其他编译器(clang, msvc)显示结果都是2
gcc似乎对char cc[]="";这种初始化,strlen(cc)直接被替换成0,strlen没有被调用。如果换成其他形式,比如char cc[]="1";char cc[2]="";strlen就会被调用,显示2.
https://godbolt.org/z/dTb84G31c

这不是动态数组,此处数组越界访问了,此处数组cc 的有效字节容量为1,所以只能改那一个元素。

这个跟你的编译器有关系,按照 C 语言理论来看,你的例子值应该是2,同时也会给你搞错。因为你确实是越界了,用到别人的内存了

我用VS2019试验,要看编译生成的是debug版本还是release版本,下面两图是debug模式编译的结果,和 release刚好相反的结果。不管什么结果,数组越界是肯定的,只是编译器尽量想做的完美些。

img

img

数组cc的大小为1,所以

cc[1] = 'b';
cc[2] = '\0';

是错误的。

不妨把char cc[]=""换成char cc[20],这表示数组cc最多可以存20个字符。