void *

M

Martin Jensen

Hi

First of, I know that void* usually is a bad idea to use, but I still want
to figure out this problem.

I assign the adress of a value to the void* and tries to retrive it again.
When I try to cast it back to a string* and get the content, something
strange happens. See the comments in the code.

This is the stipped down version of the code. It compiles and runs.

#include <string>
#include <sstream>
#include <iostream>

using std::cout;
using std::endl;
using std::eek:stringstream;
using std::string;

struct Variable {
void* value;
int type;

void setString(string s) {
value = &s;

// This prints out the memory adress of the value and it's content.
// This prints correctly.
cout << value << endl << *(string*)value << endl;
}

string getString() {
string* ret = (string*)value;

// This prints the same memory adress as above, but the content of the
value
// doesn't print correctly. The content is printed, but it doesn't seem
to stop
// what it encounters to \0. It just continues to write out content from
memory
// until it encounters segmentation fault.
cout << ret << endl << *ret << endl;
return *ret;
}
};

int main() {
Variable a;
a.setString("TEST");

string s = a.getString();
cout << s << endl;
return 0;
}



Thanks in advance
Martin Jensen
 
J

Jonathan Turkanis

Martin Jensen said:
I assign the adress of a value to the void* and tries to retrive it again.
When I try to cast it back to a string* and get the content, something
strange happens. See the comments in the code.


struct Variable {
void* value;
int type;

void setString(string s) {
value = &s;

Here's the problem: you're storing the address of a copy of the string
passed to setString. If you passed by const reference here, the
address would be valid for the lifetime of the string to which the
reference refers. It still wouldn't be very safe.
}

string getString() {
string* ret = (string*)value;

Jonathan
 
D

David White

Martin Jensen said:
Hi

First of, I know that void* usually is a bad idea to use, but I still want
to figure out this problem.

I assign the adress of a value to the void* and tries to retrive it again.
When I try to cast it back to a string* and get the content, something
strange happens. See the comments in the code.

This is the stipped down version of the code. It compiles and runs.

#include <string>
#include <sstream>
#include <iostream>

using std::cout;
using std::endl;
using std::eek:stringstream;
using std::string;

struct Variable {
void* value;
int type;

void setString(string s) {
value = &s;

You can't do this. 's' is a temporary object. Exactly what object did you
think you were taking the address of here? Where is it? If you are going to
keep a pointer to an object, you have to know that the object exists
somewhere, and will stay existing for the life of the pointer.
// This prints out the memory adress of the value and it's content.
// This prints correctly.

Yes, because the string 's' still exists here, and will until this function
returns.
cout << value << endl << *(string*)value << endl;
}

string getString() {
string* ret = (string*)value;

// This prints the same memory adress as above, but the content of the value
// doesn't print correctly. The content is printed, but it doesn't seem to stop
// what it encounters to \0. It just continues to write out content from memory
// until it encounters segmentation fault.
cout << ret << endl << *ret << endl;

Because 'value' no longer points to a valid object.
return *ret;
}
};

int main() {
Variable a;
a.setString("TEST");

Here, the string literal "TEST" is automatically converted to a temporary
string object (because that's what the function you are calling expects),
but when the function returns, what happens to it? It disappears, but your
Variable object is keeping a pointer to it.
string s = a.getString();
cout << s << endl;
return 0;
}

So, you problem has nothing to do with void *.

DW
 
D

Dave

Martin Jensen said:
Hi

First of, I know that void* usually is a bad idea to use, but I still want
to figure out this problem.

I assign the adress of a value to the void* and tries to retrive it again.
When I try to cast it back to a string* and get the content, something
strange happens. See the comments in the code.

This is the stipped down version of the code. It compiles and runs.

#include <string>
#include <sstream>
#include <iostream>

using std::cout;
using std::endl;
using std::eek:stringstream;
using std::string;

struct Variable {
void* value;
int type;

void setString(string s) {
value = &s;

// This prints out the memory adress of the value and it's content.
// This prints correctly.
cout << value << endl << *(string*)value << endl;
}

string getString() {
string* ret = (string*)value;

// This prints the same memory adress as above, but the content of the
value
// doesn't print correctly. The content is printed, but it doesn't seem
to stop
// what it encounters to \0. It just continues to write out content from
memory
// until it encounters segmentation fault.
cout << ret << endl << *ret << endl;
return *ret;
}
};

int main() {
Variable a;
a.setString("TEST");

string s = a.getString();
cout << s << endl;
return 0;
}



Thanks in advance
Martin Jensen

You're storing the address of a by-value parameter to SetString(). By the
time you use that address, the string object it refers to has gone out of
scope and been destroyed.
 
M

Martin Jensen

Jonathan Turkanis said:
Here's the problem: you're storing the address of a copy of the string
passed to setString. If you passed by const reference here, the
address would be valid for the lifetime of the string to which the
reference refers. It still wouldn't be very safe.

Thanks.


-Martin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top