tags:

views:

164

answers:

6

I'm declaring a struct inside my code and then trying to insert it into a data structure that I have written. However, I'm concerned that since I declare the struct inside the function, once the function ends, the data structure will be pointing to garbage. Can anyone help with this?

Here's the code:

 void Class::function()
 {
  // do some stuff
  node newNode;
  newNode.memAddr = tempNode.memAddr+totalSize;
  newNode.size = tempNode.size-totalSize;
  lists[newNode.size>=512?64:(newNode.size>>3)].insert(&newNode);
 }

Edit: I'm actually trying to re-write malloc, so calling malloc() or new will not work here. Is there some way that I could move this code into the insert method and then make it work in a way that it would not fall out of scope in insert?

+3  A: 

It will be out of scope after function returns, yes. That is not valid. You want to allocate it on the heap.

Edit: Unless you copy the memory you point to in insert, of course.

jfclavette
Funny you should say that because I'm actually trying to re-write malloc... :)
samoz
+1  A: 

This will almost certainly cause an error. The problem is that you're passing in an address to a value on the stack to a list that will live beyond the value. If the list is storing node* types then this will be incorrect.

To get this to work you need to do one of the following

  1. Have the list instance store node values instead of node*.
  2. Allocate the node* on the heap before passing it in. This means you will have to free it later.
JaredPar
Unless Node is really small, you probably don't want to use option #1.
Steve Rowe
@Steve, based on the limited sample, that appears to be the case. Looks to be two values, one a pointer and one likely size_t. This is is small enough to use by value .
JaredPar
+1  A: 

newNode will be out of scope, and its address will be pointing to garbage (as jfclavette noted.)

But, if by some chance

 lists[newNode.size>=512?64:(newNode.size>>3)].insert(&newNode)

is implemented to copy newNode, then the data in that copy would probably be OK, based on the limited snippet of code that you've posted.

Dan Breslau
A: 

As others have noted, this will result in a pointer being stored which will point to the stack. The stack being very busy, it's very likely it will point to something you'll care a lot about very quickly, so you'll find the problem at run time pretty fast.

Better to allocate it on the heap (using new) and deallocate it at another time.

Edit: removed note that "Your compiler should have warned you about taking the address of a stack allocated object (&newNode)." Your compiler will warn you if you attempt to return a reference to a stack object, but not if you just attempt to take a pointer.

Sebastian Good
There is absolutely nothing wrong with taking the address of a stack object, and his compiler will not warn him about it. The only valid warning is if he was returning the address of a stack variable.
Don Neufeld
I don't think I've seen compilers warn about that. There are plenty of cases where it's fine (scanf and cohorts for example) so I imagine it could get pretty annoying if they did.
Peter
A: 

To answer the edit: no.

sharth
A: 

Why are you trying to implement malloc? Unless you are writing the operating system, you probably don't want to do that. Ultimately you need to call into the OS's heap functions which malloc does for you. If you just want more control over how things are allocated, look into placement new.

Steve Rowe