10 c++ pointers return-type return-value
我试图了解如何在以下场景中返回指针:
#include <iostream>
using namespace std;
// Why does this work? I can even pass the return value to another function
// and the contents do not change.
char* StringFromFunction()
{
char* pReturn = "This string was created in the function.";
return pReturn;
}
// I know this is wrong because the memory address where 5 is stored can be
// overwritten.
int* IntegerFromFunction()
{
int returnValue = 5;
return &returnValue;
}
int main()
{
int* pInteger;
char* pString;
pString = StringFromFunction();
pInteger = IntegerFromFunction();
cout << *pInteger << endl << pString << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
程序输出正如我所期望的那样:
5
This string was created in the function.
Run Code Online (Sandbox Code Playgroud)
我在Visual C++ 2010 Express中获得的唯一编译器警告是" c:\ vc2010projects\test\main.cpp(14):警告C4172:返回本地变量或临时的地址 ",它仅显示我何时使用IntegerFromFunction()而不是StringFromFunction().
我认为我从上面的例子中理解的是以下内容:
在里面StringFromFunction(),文本的内存分配"这个字符串是在函数中创建的".在执行时发生,因为它是一个字符串文字,即使在函数返回后内容仍然存在于内存中,这就是为什么指针pStringin main()可以传递给另一个函数并且字符串可以显示在其中.
但是,对于IntegerFromFunction(),当函数返回时,现在释放分配的内存,因此可以覆盖该内存地址.
我想我的主要问题是,在整个程序中是否可以安全地传递指向字符串文字的指针?
查看差异的最简单方法是生成一个简单的 hello-world-ish 示例的反汇编:
char* test() {
return "Test";
}
int main(int argc, char* argv[]) {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是 FreeBSD 中 gcc 的反汇编,优化关闭
.file "hellow.c"
.section .rodata
.LC0:
.string "test"
.text
.p2align 4,,15
.globl test
.type test, @function
test:
pushl %ebp
movl %esp, %ebp
movl $.LC0, %eax
popl %ebp
ret
.size test, .-test
.p2align 4,,15
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
call test
movl $0, %eax
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.ident "GCC: (GNU) 4.2.1 20070719 [FreeBSD]"
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,字符串文字本身存储在 .LC0 部分中,而不是代码本身中。测试函数仅返回指向 .LC0 开头的指针(movl $.LC0, %eax),因为这是第一个字符串文字。该位置相似(但不相同),具体取决于您要编译到的可执行格式。读取A.out(文本段)或PE。