0
#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;
}

The above program prints nothing. My understanding is that when the if statement exits, variable bar which was allocated on the stack doesn't exist anymore and foo.bar holds a pointer to a undefined memory location in the stack. What I do not understand is that when I change the line to the currently commented-out line (marked with version 2). It gives me segmentation fault. Can anyone help me understand why that's the case? Also, if I want to print "test" for this program, what code changes I have to make?

3 Answers 3

1

When you construct a Foo using

Foo foo;

the member foo.bar is uninitialized. Dereferencing an uninitialized pointer is cause for undefined behavior. In your case, the undefined behavior manifests as segmentation fault.

Also, if I want to print "test" for this program, what code changes I have to make?

  1. Allocate memory for foo.bar.
  2. Assign bar to *(foo.bar) after memory is allocated.
  3. Make sure to deallocate memory before the function ends.
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;
}
Sign up to request clarification or add additional context in comments.

3 Comments

But why int* a; *a=1; works? because of primitive type?
@pippo, that is also cause for undefined behavior.
No, int* a; *a=1; is just as bad. It is however possible, that by accident you've found a valid memory address.
0

Heyy,
You had a problem with the code. The statement cout at the last that was supposed to print Test was out of the if scope. Given below is the fully functional code.
It works fine

#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;
}

3 Comments

You had made no mistake just you had closed 'if' at the wrong place which made bar and str inaccessible. I gave you nothing new, just changed the place of the bracket. your program remains the same
it was my intention to have the closing brackets where it is in my program, so that i can test if i can access foo.bar->str. i understand that your change will make the code work. tks.
O really!! That's good then brother. Then you must be knowing why you are getting a segmentation fault?
0

2). It gives me segmentation fault. Can anyone help me understand why that's the case?

For *(foo.bar) = bar;, you're trying to dereference a pointer, which you haven't allocate memory for it, i.e. dangling pointer. It would be undifined behaviour.

Also, if I want to print "test" for this program, what code changes I have to make?

Allocate memory before dereference it.

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

Don't forget to delete it at last.

1 Comment

tks for those references!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.