Why member string acts different from member int

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct a {

   string c;

   a(string x) {
       c = x;
   }
   
};


int main()
{   

   map <int, a*> m;
   m[1] = &a("hej");
   cout << m[1]->c;

}

Outputs nothing. However, if I change the parameter in "struct a" to take a int instead of a string it outputs the int. So why nothing if it's a string?
Last edited on
What is the lifetime of the unnamed temporary object that your create on line 16?

Doesn't your compiler say something like:
 In function 'int main()':
16:19: error: taking address of temporary [-fpermissive]



To answer your question:
Nothing is "valid" undefined behaviour.
Last edited on
No it runs the program without errors. Is it temporary because I didnt create a copy/instance and used the struct name directly?
Is it temporary because I didnt create a copy/instance and used the struct name directly?
Correct. &a("hej") says "construct me an a object, call a::a("hej") to initialize it, and take it's address.
To bad this way couldn't return a valid copy to use. Less code ;)
Make your compiler more verbose and pedantic, if you can.

Unnamed objects live only in the scope of the statement.

You do the equivalent of this:
1
2
3
4
5
6
7
a* p = nullptr;
{
  a v("hej");
  p = &v;
  cout << p->c; // valid
} // v is destructed here
cout << p->c; // error: dereferencing dangling pointer 

On line 7 the p still has the address that it got on line 4, but the object (v) that was on that memory location does not exists any more.
Old versions of MSVC and GCC used to only issue a warning diagnostic for taking the address of a temporary, but any even somewhat-recent compiler should error out... I suggest updating your compiler. But even on an outdated compiler, it should at least be a warning, so ALWAYS compile with at least -Wall on GCC, and turn on extra/pedantic too for good measure.
@Ganado, I'd add to your suggestions....when using MSVC set the warning level to 4. Anything higher and you get gobs of unnecessary and useless warnings about the C++ standard library.
To bad this way couldn't return a valid copy to use. Less code ;)

Drop * and & and you get both less and valid code.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <string>
#include <map>
#include <iostream>

struct a {
   std::string c;
};

int main()
{
   std::map<int, a> m;
   m[1] = a{"hej"};
   std::cout << m[1].c;
}
keskiverto this was very helpful. Thanks alot
Topic archived. No new replies allowed.