Stack Memory Deallocation Problem

Y

yccheok

Hi, i am from java background and c++ is quite new for me. Consider the
following code:

i obtain an warning from my compiler which states:
a.cpp:45: warning: taking address of temporary

it seems that i am facing problem in accessing an object which has
already been deallocated in stack memory.

unliked java, the object will not be allocated as long as there is a
reference pointing to it.

in c++ case, is there any way to solve this problem without using
dynamic memory allocation (new and delete)?

thank you very much!

-cheok

#include <iostream>

using namespace std;

class a {
int name;

public:
a(int);
~a();
int getName();
a createA(int);
};

a::a(int value) {
name = value;
cout<< "a named "<< name<< " is created"<< endl;
}

a::~a() {
cout<< "a named "<< name<< " is DELETED"<< endl;
}

int a::getName() {
return name;
}


a a::createA(int i) {
a aa(i);
return aa;
}

int main() {
int i=0;
a solidA(100);
a* tmp;

while(true) {
if(i > 0) {
cout<< "am i access 'a' which has been
deleted?? "<< tmp->getName()<< endl;
}

cout<< "creating 'a' and preparing to assign it to a
reference..."<< endl;
tmp = &(solidA.createA(i));

// tmp is now holding 'a' which already been deleted in
stack memory.
i++;
}
}
 
V

Victor Bazarov

Hi, i am from java background and c++ is quite new for me. Consider the
following code:

i obtain an warning from my compiler which states:
a.cpp:45: warning: taking address of temporary

it seems that i am facing problem in accessing an object which has
already been deallocated in stack memory.

unliked java, the object will not be allocated as long as there is a
reference pointing to it.

in c++ case, is there any way to solve this problem without using
dynamic memory allocation (new and delete)?

Yes, don't use the pointer, use an object (just like you would in Java).
thank you very much!

-cheok

#include <iostream>

using namespace std;

class a {
int name;

public:
a(int);
~a();
int getName();
a createA(int);
};

a::a(int value) {
name = value;
cout<< "a named "<< name<< " is created"<< endl;
}

a::~a() {
cout<< "a named "<< name<< " is DELETED"<< endl;
}

int a::getName() {
return name;
}


a a::createA(int i) {
a aa(i);
return aa;

The two lines can be simply merged resulting in

return a(i);
}

int main() {
int i=0;
a solidA(100);
a* tmp;

Drop the asterisk.
while(true) {
if(i > 0) {
cout<< "am i access 'a' which has been
deleted?? "<< tmp->getName()<< endl;

Replace -> with .
}

cout<< "creating 'a' and preparing to assign it to a
reference..."<< endl;
tmp = &(solidA.createA(i));

There is no "reference" here to assign to. Straighten up your messages.

What happens here is simple: you're returning a value from a function.
It's what is known as "rvalue". First of all, you're not supposed to be
able to take an address of it. Second of all, the temporary that you try
to take the address of, only lives until the end of the full expression
(in this case until the semicolon).

Just do

tmp = solidA.createA(i);
// tmp is now holding 'a' which already been deleted in
stack memory.

Yes, but if you switch to an object instead, everything is going to work
just fine.

V
 
P

Paavo Helde

(e-mail address removed) wrote in @f14g2000cwb.googlegroups.com:
Hi, i am from java background and c++ is quite new for me. Consider the
following code:

i obtain an warning from my compiler which states:
a.cpp:45: warning: taking address of temporary

it seems that i am facing problem in accessing an object which has
already been deallocated in stack memory.

You are guessing right.

#include <iostream>

using namespace std;

class a {
int name;

public:
a(int);
~a();
int getName();

This should be marked 'const' as it doesn't alter object state:

int getName() const;
a createA(int);

A factory function is commonly declared static, so you don't need an
existing object for calling the function:

static a CreateA(int);

};

a::a(int value) {
name = value;
cout<< "a named "<< name<< " is created"<< endl;
}

a::~a() {
cout<< "a named "<< name<< " is DELETED"<< endl;
}

int a::getName() {
return name;
}


a a::createA(int i) {
a aa(i);
return aa;
}

int main() {
int i=0;
a solidA(100);
a* tmp;

while(true) {
if(i > 0) {
cout<< "am i access 'a' which has been
deleted?? "<< tmp->getName()<< endl;
}

cout<< "creating 'a' and preparing to assign it to a
reference..."<< endl;
tmp = &(solidA.createA(i));

Yes, the temporary object returned by createA() is destroyed at the
semicolon.

You have two possibilities (apart of dynamic allocation): prolong the
temporary lifetime by binding it to a const reference:

const a& tmp = solidA.createA(i);
// temporary lifetime prolonged while 'tmp' is in scope.
// note: const keyword is essential here, and that's an additional
// reason why the getName() member fn should be const.

or alternatively, store the temporary object in some buffer:

a buffer;
a* tmp;
// ...
buffer = solidA.createA(i);
tmp = &buffer;

// tmp is now holding 'a' which already been deleted in
stack memory.
i++;
}
}

Regards
Paavo
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top