return pointer to data declared in function

前端 未结 11 1570
南旧
南旧 2020-12-17 21:11

I know this won\'T work because the variable x gets destroyed when the function returns:

int* myFunction()
{
    int x = 4; return &x;
}
<
相关标签:
11条回答
  • 2020-12-17 21:26

    Your second code snippet is correct.

    To help avoid memory leaks, I let the coding conventions help me.

    xxxCreate() will allocate memory for xxx and initialize it. xxxDelete() will destroy/corrupt xxx and free it.

    xxxInit() will initialize xxx (never allocate) xxxDestroy() will destroy/corrupt xxx (never free)

    Additionally, I try to add the code to delete/destroy/free as soon as I add the code to create/init/malloc. It's not perfect, but I find that it helps me differentiate between items that need to be freed and those that don't, as well as reducing the likelihood that I will forget to free something at a later time.

    0 讨论(0)
  • 2020-12-17 21:27

    In C++, you should use new:

    int *myFunction()
    {
        int blah = 4;
        return new int(blah);
    }

    And to get rid of it, use delete:

    int main(void)
    {
        int *myInt = myFunction();
        // do stuff
        delete myInt;
    }

    Note that I'm invoking the copy constructor for int while using new, so that the value "4" is copied onto the heap memory. The only way to get a pointer to something on the stack reliably is to copy it onto the heap by invoking new properly.

    EDIT: As noted in another answer, you will also need to document that the pointer needs to be freed by the caller later on. Otherwise you might have a memory leak.

    0 讨论(0)
  • 2020-12-17 21:28

    Your second approach is correct. You just need to clearly document that the caller "owns" the result pointer, and is responsible for freeing it.

    Because of this extra complexity, it is rare to do this for "small" types like int, though I'm assuming you just used an int here for the sake of an example.

    Some people will also prefer to take a pointer to an already allocated object as a parameter, rather than allocating the object internally. This makes it clearer that the caller is responsible for deallocating the object (since they allocated it in the first place), but makes the call site a bit more verbose, so it's a trade-off.

    0 讨论(0)
  • 2020-12-17 21:33

    There is another approach - declare x static. In this case it will be located in data segment, not on stack, therefore it is available (and persistent) during the program runtime.

    int *myFunction(void)
    {
        static int x = 4;
        return &x;
    }
    

    Please note that assignment x=4 will be performed only on first call of myFunction:

    int *foo = myFunction();   // foo is 4
    *foo = 10;                 // foo is 10
    *foo = myFunction();       // foo is 10
    

    NB! Using function-scope static variables isn't tread-safe technique.

    0 讨论(0)
  • 2020-12-17 21:34

    You're asking how to correctly return a pointer. That's the wrong question, because what you should be doing is using smart pointers rather than raw pointers. scoped_ptr and shared_ptr (available in boost and tr1) are good pointers to look at (e.g. here and here)

    If you need the raw pointer for something (e.g. passing to a C function), the get() method will supply it.

    If you must create raw pointers, e.g. for homework, then you can use malloc() (as you did) or new within a function, and hope you remember to de-allocate the memory (through free() and delete respectively) Or, in a slightly-less-likely-to-leak idiom, you can create the pointer with new, pass it to a function, and de-allocate with delete when you're done with it. Again, though, use smart pointers.

    0 讨论(0)
  • 2020-12-17 21:35

    I would try something like this:

    int myFunction2b( int * px )
    {
      if( px )
      {
        *px = 4;
        return 1;
      }
    
      // Choice 1: Assert or Report Error
      // Choice 2: Allocate memory for x. Caller has to be written accordingly.
    
      // My choice is 1
      assert( 0 && "Argument is NULL pointer" );
      return 0;
    
    }
    
    0 讨论(0)
提交回复
热议问题