C++ 我在函数中有一个本地字符数组-当我返回数组名时,为什么返回值为空?

C++ 我在函数中有一个本地字符数组-当我返回数组名时,为什么返回值为空?,c++,C++,我遇到了一件非常令人困惑的事情。我在一个函数中创建了一个本地字符数组,并返回数组名,但返回值为null char* get_string(){ char local[] ="hello world\n"; cout<<"1"<<(int)local<<endl;//shows a reasonable value return local; } int main(){ char* p = get_string(); c

我遇到了一件非常令人困惑的事情。我在一个函数中创建了一个本地字符数组,并返回数组名,但返回值为null

char* get_string(){
    char local[] ="hello world\n";
    cout<<"1"<<(int)local<<endl;//shows a reasonable value
    return local;
}

int main(){
    char* p = get_string();
    cout<<"2"<<(int) p<<endl;//shows 0
    return 0;
}

我认为这是在编译器中定义的、硬编码的,如果我返回一个局部变量的地址,则%Eax或%RAX设置为0。

< P> C++标准称引用最新草案:

[basic.stc]

当到达存储区域的持续时间结束时,表示该存储区域任何部分的地址的所有指针的值将变为无效指针值。 通过无效指针值的间接寻址和将无效指针值传递给解除分配函数具有未定义的行为。 无效指针值的任何其他使用都具有实现定义的行为

p包含无效的指针值,并且在任何其他用途中都包括打印指针值,因此行为由实现定义。在观察到的情况下,行为输出为0

请读者注意,在示例中的代码中,没有通过无效指针的间接寻址,并且行为也不是未定义的


另外,将指针转换为int不正确。int不能保证足够大以表示所有指针值,而且在大多数64位系统上,它也不够大。标准仅指定转换为足够大的整数类型的行为。在这种情况下,我建议将其转换为void*。

@wangz由于数组在退出函数后不活动,因此代码具有未定义的行为。这是一个教训,未定义的行为意味着任何事情都可能发生。这并不意味着哦,可能是堆栈bla bla this和that等。未定义的行为就是这样-未定义且难以预测。如果我不得不猜测的话,我会说编译器发现您返回的是一个局部变量的地址,并用nullptr替换它以允许调用代码捕获此错误。首先,指针可能不适合int,其次,没有任何帮助,您的期望完全错了。可能是重复的,或者谢谢,我检查了汇编代码,在从函数返回之前,请看%eax被设置为0。我认为这是实现定义的,您认为int可能不够大,无法容纳指针,在这种情况下,这是可以的,因为我知道我会将其编译为32位代码,但使用void*并按十六进制打印出来better@wangz如果要将指针转换为整数,使用std::intptr\t。
0x44bce7  mov $0x0,%eax 
0x44bcec     leave
0x44bced     ret