Jump to content
  • Advertisement
Sign in to follow this  
slicer4ever

pointers, and memory managment questions

This topic is 2491 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hello everyone, i have a couple basic functions/memory managment questions, that i don't fully understand how c++ interprets the results.

basically:

#include <stdio.h>

class x{
private:
int m_x;
public:
int GetX(void){
return m_x;
}

x(int y) : m_x(y){}
};

x f(int z){
return x(z); //isn't this passing static stack memory?, isn't this bad programming?
}

int main(int argc, char **argv){
x y = f(5);
x z = f(10);
//are y and z static, or dynamic memory?, should i free them?
printf("%d\n", y.GetX());
printf("%d\n", z.GetX());
return 0;
}


basically, i see this in the environment i'm working in, and i've always been taught to use pointers to pass objects, like so:


#include <stdio.h>

class x{
private:
int m_x;
public:
int GetX(void){
return m_x;
}

x(int y) : m_x(y){}
};

x *f(int z){
return new x(z);
}

int main(int argc, char **argv){
x *y = f(5);
x *z = f(10);
printf("%d\n", y->GetX());
printf("%d\n", z->GetX());
delete y;
delete z;
return 0;
}



so hopefully some of my questions can be cleared up.

Share this post


Link to post
Share on other sites
Advertisement


x f(int z){
return x(z); //isn't this passing static stack memory?, isn't this bad programming?
}

[/quote]

What happens here is that an unnamed temporary x is constructed on the stack space. When the function returns, the temporary object is then copied into the stack space allocated for main's y, and the temporary is destructed. The compiler may elide this unnecessary copy via RVO, and will probably optimize such that the unnnamed temporary in f constructs directly into main's y. (It is not bad programming practice.)

Now, returning the address of a temporary is a bad programming practice because the memory allocated for the unnamed temporary expires as soon as the function returns.

x& f(int z) {
return x(z);
}


Note that memory management only applies to dynamically allocated memory, since they have an unrestricted scope, e.g. stack allocations have a strict ordering as to the allocation and deallocation of memory (LIFO), whereas heap allocations are deallocated in any order. Stack allocations are faster than heap allocations because of this assumption -- a stack allocation simply increments/decrements the stack pointer (LIFO algorithm), and a heap allocation requires a data structure to track allocations (tree/list, etc).

Basically, delete what you new, delete[] what you new[], and free what you malloc.

Share this post


Link to post
Share on other sites



x f(int z){
return x(z); //isn't this passing static stack memory?, isn't this bad programming?
}



What happens here is that an unnamed temporary x is constructed on the stack space. When the function returns, the temporary object is then copied into the stack space allocated for main's y, and the temporary is destructed. The compiler may elide this unnecessary copy via RVO, and will probably optimize such that the unnnamed temporary in f constructs directly into main's y. (It is not bad programming practice.)
[/quote]

so, in a sense, it's just using the stack space of the declared variable y, doesn't this cause overhead to copy what's created in the function(assuming the compiler doesn't do rvo)?

Share this post


Link to post
Share on other sites



x f(int z){
return x(z); //isn't this passing static stack memory?, isn't this bad programming?
}



Now, returning the address of a temporary is a bad programming practice because the memory allocated for the unnamed temporary expires as soon as the function returns.

[/quote]

That's not exactly true. In C++, the example he showed:

x* f(int z)
{
return new x(z);
}


Will return a pointer to an address on the heap, which won't be destroyed until delete is called, or the program terminates (although, it really should be done via delete). Which he does via the delete y and delete z at the end of his code.

Share this post


Link to post
Share on other sites

[quote name='fastcall22' timestamp='1329163278' post='4912707']


x f(int z){
return x(z); //isn't this passing static stack memory?, isn't this bad programming?
}



Now, returning the address of a temporary is a bad programming practice because the memory allocated for the unnamed temporary expires as soon as the function returns.

[/quote]

That's not exactly true. In C++, the example he showed:

x* f(int z)
{
return new x(z);
}


Will return a pointer to an address on the heap, which won't be destroyed until delete is called, or the program terminates (although, it really should be done via delete). Which he does via the delete y and delete z at the end of his code.
[/quote]
But that's not very nice code as you are hiding away a dynamic memory allocation, and you should never return pointers from a function where it isn't completely clear who owns them. When you have:

RenderInstance* createRenderInstance();

That function name informs you it is going to create something and hand you a pointer back to it, you own this pointer if this function isn't part of some manager class. However a function like this:

RenderInstance* getRenderInstance();

This clearly means you do not own this pointer is only there to read from or modify the object.

An even better pattern is to pass the storage location of the object to create in like so

bool createRenderInstance(RenderInstance*& instance);
//or
RenderInstance* createRenderInstance(RenderInstance*& instance) //in this case the return value is the created pointer that was passed to the function
{
instance = new RenderInstance();
return instance;
}

This way you pass it a pointer and it will fill it in with the new address location of the instance.

Share this post


Link to post
Share on other sites

[quote name='BeerNutts' timestamp='1329167832' post='4912742']
[quote name='fastcall22' timestamp='1329163278' post='4912707']


x f(int z){
return x(z); //isn't this passing static stack memory?, isn't this bad programming?
}



Now, returning the address of a temporary is a bad programming practice because the memory allocated for the unnamed temporary expires as soon as the function returns.

[/quote]

That's not exactly true. In C++, the example he showed:

x* f(int z)
{
return new x(z);
}


Will return a pointer to an address on the heap, which won't be destroyed until delete is called, or the program terminates (although, it really should be done via delete). Which he does via the delete y and delete z at the end of his code.
[/quote]
But that's not very nice code as you are hiding away a dynamic memory allocation, and you should never return pointers from a function where it isn't completely clear who owns them. When you have:

RenderInstance* createRenderInstance();

That function name informs you it is going to create something and hand you a pointer back to it, you own this pointer if this function isn't part of some manager class. However a function like this:

RenderInstance* getRenderInstance();

This clearly means you do not own this pointer is only there to read from or modify the object.

An even better pattern is to pass the storage location of the object to create in like so

bool createRenderInstance(RenderInstance*& instance);
//or
RenderInstance* createRenderInstance(RenderInstance*& instance) //in this case the return value is the created pointer that was passed to the function
{
instance = new RenderInstance();
return instance;
}

This way you pass it a pointer and it will fill it in with the new address location of the instance.
[/quote]

My comment was directed at this specific comment:

because the memory allocated for the unnamed temporary expires as soon as the function returns.
[/quote]
It had nothing to do with the good programming. Hell, Obviously, he's not naming the class x, and the function f. It was just an example, not a real world piece of code.

Share this post


Link to post
Share on other sites

[quote name='fastcall22' timestamp='1329163278' post='4912707']
Now, returning the address of a temporary is a bad programming practice


That's not exactly true. In C++, the example he showed:

x* f(int z)
{
return new x(z);
}

[/quote]

Let me help you out with an important bolding of key words.

Nothing about "new" is "temporary"

Share this post


Link to post
Share on other sites

[quote name='fastcall22' timestamp='1329163278' post='4912707']


x f(int z){
return x(z); //isn't this passing static stack memory?, isn't this bad programming?
}



Now, returning the address of a temporary is a bad programming practice because the memory allocated for the unnamed temporary expires as soon as the function returns.

[/quote]

That's not exactly true. In C++, the example he showed:

x* f(int z)
{
return new x(z);
}


Will return a pointer to an address on the heap, which won't be destroyed until delete is called, or the program terminates (although, it really should be done via delete). Which he does via the delete y and delete z at the end of his code.
[/quote]
Beernutts, you and fastcall22 are talking about two different pieces of code. None of the code slicer4ever posted returns the address of a temporary, which is what fastcall22 explained. Though fastcall22 did post a small example snippet that does return the address of a temporary to illustrate what he was talking about, it's not the code you've quoted. You probably misunderstood fastcall22's post and took that quote out of context.

Share this post


Link to post
Share on other sites

[quote name='BeerNutts' timestamp='1329167832' post='4912742']
[quote name='fastcall22' timestamp='1329163278' post='4912707']
Now, returning the address of a temporary is a bad programming practice


That's not exactly true. In C++, the example he showed:

x* f(int z)
{
return new x(z);
}

[/quote]

Let me help you out with an important bolding of key words.

Nothing about "new" is "temporary"
[/quote]
Let me help you with the internetz. You replied to the wrong guy.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!