Basic C++ question

irishScott

Lifer
Oct 10, 2006
21,562
3
0
If I make a function that returns a pointer like so...

class* function(void)
{
class* returnClass = new class();
return returnClass;
}

int main(void)
{
class* cPointer = function();

return 0;
}

Is the class object pointed to by cPointer considered temporary? Just wondering cause I appear to having a problem with memory corruption in a similar scenario.
 

xtknight

Elite Member
Oct 15, 2004
12,974
0
71
I think the returnClass pointer is being freed at the end scope of function(), and therefore cPointer is. You could print out the value of cPointer in number format and see.
 

graemenz

Member
Jul 19, 2005
26
0
0
No, the class object is absolutely NOT temporary. Heap objects are never temporary. Your code won't result in corruption but it stands a good chance of leaking memory.

 

Cogman

Lifer
Sep 19, 2000
10,286
147
106
Originally posted by: graemenz
No, the class object is absolutely NOT temporary. Heap objects are never temporary. Your code won't result in corruption but it stands a good chance of leaking memory.

Exactly true. the new command makes everything scope defying until the delete command is called.

If you had done

class* function()
{
class thing;
return &thing;
}
ect...

Then you would risk memory corruption, but not the solution you have above.
 

exdeath

Lifer
Jan 29, 2004
13,679
10
81
The 4 bytes used for the pointer cPointer is temporary. The memory it points to however is not and is lost the moment main::cPointer falls out of scope. In this example it wont be a problem, because when main terminates, you'll leak memory, but shortly after the process is destroyed anyway. In a function other than main called multiple times, your application would grow in memory consumption as it runs.

Memory allocated with new/malloc must be tracked or reference counted in some way so there is a corresponding delete/free. If all your local pointers to the memory allocated by new go out of scope with no way to find it again and delete it, the memory becomes orphaned and occupies the heap until program termination.
 

Cogman

Lifer
Sep 19, 2000
10,286
147
106
Originally posted by: exdeath
The 4 bytes used for the pointer cPointer is temporary. The memory it points to however is not and is lost the moment main::cPointer falls out of scope. In this example it wont be a problem, because when main terminates, you'll leak memory, but shortly after the process is destroyed anyway. In a function other than main called multiple times, your application would grow in memory consumption as it runs.

Memory allocated with new/malloc must be tracked or reference counted in some way so there is a corresponding delete/free. If all your local pointers to the memory allocated by new go out of scope with no way to find it again and delete it, the memory becomes orphaned and occupies the heap until program termination.

This is correct. I guess that it is important that you remember that a function like this passes that responsibility of freeing memory on to the users of the function.

But again, this form you have written will not result in data corruption / loss.
 
Sep 29, 2004
18,656
68
91
In C++, returning pointers is bad practice unless it is because of a singleton. Implement operator=() and use deep copies of classes. Do everything this way. If your code runs to slow in the end, then you should optimize.

Like this:
Foo function()
{
Foo thing;
return thing;
}

You need to implement Foo::eek:perator=() to do this though. Of course, if you do not have pointers as fields, the compiler will handle things for you.
 

degibson

Golden Member
Mar 21, 2008
1,389
0
0
Originally posted by: IHateMyJob2004
In C++, returning pointers is bad practice unless it is because of a singleton. Implement operator=() and use deep copies of classes. Do everything this way. If your code runs to slow in the end, then you should optimize.

Like this:
Foo function()
{
Foo thing;
return thing;
}

You need to implement Foo::eek:perator=() to do this though. Of course, if you do not have pointers as fields, the compiler will handle things for you.

It all depends on sizeof(Foo)
 

sao123

Lifer
May 27, 2002
12,656
207
106
Originally posted by: irishScott
If I make a function that returns a pointer like so...

class* function(void)
{
class* returnClass = new class();
return returnClass;
}

int main(void)
{
class* cPointer = function();

return 0;
}

Is the class object pointed to by cPointer considered temporary? Just wondering cause I appear to having a problem with memory corruption in a similar scenario.


your operation is failing because you have not defined how the = operator works on a object of your class. Without a memberwise copy function defined for the = operator, the bolded statement fails. It took me several hours on a project to figure out this important piece of knowledge.
 

Cogman

Lifer
Sep 19, 2000
10,286
147
106
Originally posted by: sao123
Originally posted by: irishScott
If I make a function that returns a pointer like so...

class* function(void)
{
class* returnClass = new class();
return returnClass;
}

int main(void)
{
class* cPointer = function();

return 0;
}

Is the class object pointed to by cPointer considered temporary? Just wondering cause I appear to having a problem with memory corruption in a similar scenario.


your operation is failing because you have not defined how the = operator works on a object of your class. Without a memberwise copy function defined for the = operator, the bolded statement fails. It took me several hours on a project to figure out this important piece of knowledge.

That would be incorrect. A pointer is a pointer is a pointer. it doesn't matter if it is a class pointer, an integer pointer, or a void pointer it is still a pointer.

When you have a function returning a pointer, all that is being sent back is the address for the object. Nothing else. The object is not being copied or changed in any way from this statement.

If you don't believe me, here is some real code that essentially does what the OP did.

#include <iostream>

using namespace std;

class Test
{
public:
int data;
};

Test* isData()
{
Test* out;
out = new Test();
out->data = 2;
return out;
}

int main()
{
Test* in;
in = isData();
cout << in->data << endl;
delete in;
return 0;
}
 

irishScott

Lifer
Oct 10, 2006
21,562
3
0
Thanks for the help guys. I ended up making a copy constructor that accepted a class* like so:

class* object = new class(function());

and of course added the appropriate delete statement to avoid memory leaks.

Seems to have fixed the corruption issue for some reason. A more detailed explanation of my problem was that the class in question required the user to input some of its parameters via a wizard-like interface using the terminal/cin. At the end of the wizard, the user enters y/n if they want to add the object to the database or not. For some reason, the y would end up in a field that the user never interacts with, and all of the cin/data manipulation statements match up (spent an hour going over it). :confused:

Regardless, it's apparently fixed now. Thanks again.
 
Sep 29, 2004
18,656
68
91
Originally posted by: degibson
Originally posted by: IHateMyJob2004
In C++, returning pointers is bad practice unless it is because of a singleton. Implement operator=() and use deep copies of classes. Do everything this way. If your code runs to slow in the end, then you should optimize.

Like this:
Foo function()
{
Foo thing;
return thing;
}

You need to implement Foo::eek:perator=() to do this though. Of course, if you do not have pointers as fields, the compiler will handle things for you.

It all depends on sizeof(Foo)

Even if Foo has 100 fields that are all arrays, this still amounts to little effort from modern hardware.
 

degibson

Golden Member
Mar 21, 2008
1,389
0
0
Originally posted by: IHateMyJob2004
Originally posted by: degibson
Originally posted by: IHateMyJob2004
In C++, returning pointers is bad practice unless it is because of a singleton. Implement operator=() and use deep copies of classes. Do everything this way. If your code runs to slow in the end, then you should optimize.

Like this:
Foo function()
{
Foo thing;
return thing;
}

You need to implement Foo::eek:perator=() to do this though. Of course, if you do not have pointers as fields, the compiler will handle things for you.

It all depends on sizeof(Foo)

Even if Foo has 100 fields that are all arrays, this still amounts to little effort from modern hardware.

If you call function() once, yes. If Foo becomes a datatype that moves all around the application... its a problem.
 
Sep 29, 2004
18,656
68
91
Originally posted by: degibson
Originally posted by: IHateMyJob2004
Originally posted by: degibson
Originally posted by: IHateMyJob2004
In C++, returning pointers is bad practice unless it is because of a singleton. Implement operator=() and use deep copies of classes. Do everything this way. If your code runs to slow in the end, then you should optimize.

Like this:
Foo function()
{
Foo thing;
return thing;
}

You need to implement Foo::eek:perator=() to do this though. Of course, if you do not have pointers as fields, the compiler will handle things for you.

It all depends on sizeof(Foo)

Even if Foo has 100 fields that are all arrays, this still amounts to little effort from modern hardware.

If you call function() once, yes. If Foo becomes a datatype that moves all around the application... its a problem.

When it becomes a problem, that is when the program should be optimized to deal with it. Even a large object cloned 100 times will probably take less than 10 ms to do so 100 times on modern hardware. And unless it is a real time piece of software with timing requirements, it should not matter unless the user experience is hampered on the target hardware or minimum target hardware.

Regardless ... this is turning into a real world discussion instead of a discussion on what seems to be an academic issue. It is my opinion that knowing how to properly code the operator=() function is worth while. Heck, it would even be a good entry level question for a software engineer that wants to do C/C++.