变量范围和指针

时间:2015-11-17 05:31:40

标签: c++ pointers

#include <iostream>
#include <string>
using namespace std;

struct Bar {
    string str;
};

struct Foo {
    Bar* bar;
};    

int main() {
    Foo foo;
    if (true) {
        Bar bar;
        bar.str = "test";
        foo.bar = &bar; // version 1
        // *(foo.bar) = bar; // version 2
    }
    cout << foo.bar->str << endl;
    return 0;
}

以上程序不打印任何内容。我的理解是,当if语句退出时,在堆栈上分配的变量bar不再存在,并且foo.bar保存指向堆栈中未定义的内存位置的指针。我不明白的是,当我将行更改为当前注释掉的行(标有版本2)时。它给了我分段错误。任何人都可以帮助我理解为什么会这样吗?另外,如果我想打印&#34; test&#34;对于这个程序,我必须做什么代码更改?

3 个答案:

答案 0 :(得分:1)

使用

构建Foo
Foo foo;

成员foo.bar未初始化。取消引用未初始化的指针是导致未定义的行为的原因。在您的情况下,未定义的行为表现为分段错误。

  

另外,如果我想打印&#34;测试&#34;对于这个程序,我必须做什么代码更改?

  1. foo.bar分配内存。
  2. 在分配内存后将bar分配给*(foo.bar)
  3. 确保在函数结束前释放内存。
  4.   
    int main() {
       Foo foo;
       if (true) {
          Bar bar;
          bar.str = "test";
          foo.bar = new std::string;
          *(foo.bar) = bar;
       }
       cout << foo.bar->str << endl;
       delete foo.bar;
       return 0;
    }
    

答案 1 :(得分:0)

  

2)。它给了我分段错误。任何人都可以帮助我理解为什么会这样吗?

对于*(foo.bar) = bar;,您尝试取消引用指针,但尚未为其分配内存,即dangling pointer。它将是undifined behaviour

  

另外,如果我想打印&#34;测试&#34;对于这个程序,我必须做什么代码更改?

在取消引用之前分配内存。

foo.bar = new Bar;
*(foo.bar) = bar;

不要忘记最后删除它。

答案 2 :(得分:0)

Heyy,你的代码有问题。应该打印测试的最后一个声明cout超出了if范围。以下是功能齐全的代码。
工作正常

#include <iostream>
#include <string>
using namespace std;

struct Bar {
    string str;
};

struct Foo {
    Bar* bar;
};    

int main() {
    Foo foo;
    if (true) {
        Bar bar;
        bar.str = "test";
        foo.bar = &bar; // version 1
        // *(foo.bar) = bar; // version 2
    //previously bracets were here which made bar out of the scope due to 
    //which str wasn't accessible.
    cout << (foo.bar->str) << endl;//you had a problem in the scope}
    return 0;
}