2013-02-15 62 views
0

在下面的代码中,我希望tmp字符数组在f()返回后被销毁,因此x根本不应该被打印。函数返回后字符数组未被破坏

但是,在下面的函数x获得打印在main()但for循环不打印正确的东西。有人可以解释这种行为。这是输出。

ABCDEFG 一个 b Ç d Ë ˚F 克 ABCDEFG ?

ķ Ÿ 我

#include <iostream> 
using namespace std; 

char* x; 
void f() 
{ 
    char tmp[100]= "abcdefg"; 
    x = tmp; 

    cout << x << endl; 
    for(int i=0; i < 7; i++) 
     cout << x[i] << endl; 
} 

int main() 
{ 
    f(); 

    cout << x << endl; 
    for(int i=0; i < 7; i++) 
     cout << x[i] << endl; 
} 
+0

定义“破坏”。 tmp在堆栈上创建。如果您在调用f()之后调用另一个方法,可能会覆盖tmp,否则编译器没有理由重写堆栈来整理事情。但是,你正在做的事情被认为是危险的。 – Pete 2013-02-15 15:22:40

+1

请选择C或C++。 – 2013-02-15 15:23:02

+0

什么是“我是”? – banuj 2013-02-15 15:23:56

回答

1

要调用未定义的行为。 f()范围关闭后,指针可能有效也可能无效。

+0

,它解释了cout << x,但是for循环中的打印字符不打印相同的字符数组。 – Pungs 2013-02-15 15:24:52

+0

你正在做很多被认为是不好或明显错误的事情。介意说明原因是什么? – 2013-02-15 15:25:56

+0

@Pungs是的,因为堆栈中的位置已被另一个数据替换,所以当您执行了'cout << x << endl;'此代码将堆栈中的数据替换为其他数据,这些数据不可打印 – banuj 2013-02-15 15:26:47

0

您正在调用UB。您访问不再为您的程序分配的内存。这仅仅是运气它在第一印刷品上运作。

3

你在做什么是未定义的行为,你有一个指向一个内存位置的指针可能会或可能不会。这不好。

实际发生的是你的char buffer tmp位于函数f()的堆栈帧上,当该函数返回数据时,堆栈上的数据将被未来的堆栈帧覆盖。

做你所做的事情的正确方法很简单。

std::string f() { 
    std::string str ("abcdefg"); 
    std::cout << str << '\n'; 
    return str; 
} 
int main() { 
    std::string s=f(); 
    std::cout << s << '\n'; 
} 
0

在程序x被定义为一个全球性的指针作为char temp[100]是在栈上分配的,其与栈上的地址进行初始化。当函数f返回时,堆栈指针递减。但是,x将继续指向相同的内存位置,该内存位置将不具有正确的值,因此会观察到错误的输出。