When I dynamically allocate mem within a function, do I have to still manually release it? Or does it go away once the function has run and returned (like local variables)?

If I do have to release it, since it's basically a pointer can I do that from main? Do I have to return the address to release it from outside the function?

I'm assuming that once the memory has been allocate, no matter from where, it must still be manually release, and the address must be passed to do this.

Recommended Answers

All 11 Replies

  1. Dynamically allocated memory is allocated in Heap and not in stack, so when the function returns, the memory in heap is still in tact and must be freed manually to prevent memory leaks.

  2. According to me, freeing it in the function itself is a better practice as it abstracts away what the function does from outside world and makes it the function's responsibility to do its own cleanup.

When I dynamically allocate mem within a function, do I have to still manually release it? Or does it go away once the function has run and returned (like local variables)?

if you dynamically allocate memory using new then you have to release it using delete or delete[].Otherwise there could be memory leak.

If I do have to release it, since it's basically a pointer can I do that from main? Do I have to return the address to release it from outside the function?

I'm keen to know more about this way.i have never done this before.but i think if you return a pointer (pointing to the memory address) , then its possible.But i again say that i have never done this before.Hope somebody could explain it deeply.

When I dynamically allocate mem within a function, do I have to still manually release it?

Yes. Everything that is allocated must be deallocated. If you allocate memory inside a function and don't release it before exiting the function, then that memory will be leaked (or in more precise terms, it will be "unreachable" memory, because it is memory that has not been freed, and has no more pointers anywhere pointing to it, and thus, "unreachable").

Or does it go away once the function has run and returned (like local variables)?

No. Local variables "go away" because they are part of the function's stack frame (static memory allocated for the duration of the function's execution). Dynamic memory is allocated on the "heap", which is not automatic, i.e., you have to manually allocate and then manually deallocate everything.

If I do have to release it, since it's basically a pointer can I do that from main?

Yes, you can do that from anywhere you want, but you do need to have the pointer value accessible.

Do I have to return the address to release it from outside the function?

Exactly. If you want to be able to release the memory from outside of the function, then you need to return the pointer that needs to be deleted. Basically, the place where you decide to release the memory from needs to know the address of the memory you want to release, otherwise it can't do it.

So, if you allocate memory inside a function, you have two choices: release it before you leave, or return the pointer value such that it can be released later.

I'm assuming that once the memory has been allocate, no matter from where, it must still be manually release, and the address must be passed to do this.

That's exactly right.

If you want to save yourself all this trouble, do as most seasoned C++ programmers do, which is to use STL containers for lists of objects and smart-pointers for individual objects. This technique is called RAII (Resource Allocation Is Initialization) and it allows you to avoid all these headaches and basically never have to worry about memory management ever again (which is the case for most practicing C++ programmers).

Here is the code illustrating the concept

int* allocate()
{
    int* p=new int;                 //dynamically allocation
    *p=10;
    return p;                       //returning pointer
}
int main()
{
    int* p1;
    p1=allocate();
    cout<<*p1<<"("<<p1<<")"<<endl; //memory still occupied
    delete p1;                      //now free it
    cout<<*(p1)<<endl;              
    return 0;
}

hope this helps you.

now my confusions :

@mike
i want this(allocate(n)) and therefore i changed declaration to this (int* allocate(int n)).And here is my code.

int* allocate(int n)
{
    int* p=new int[n];
    cout<<"base address="<<p<<endl;
    for(int i=0;i<n;i++)
    {
        cout<<"value will be stored at("<<p+i<<")";
        cin>>*(p+i);
    }
    return p;
}
int main()
{
    int n;
    cout<<"how many integers";
    cin>>n;
    int* p1;
    p1=allocate(n);
    for(int i=0;i<n;i++)
    {
        cout<<*(p1+i)<<"("<<p1+i<<")"<<endl;
    }
    delete p1;
    for(int i=0;i<n;i++)
    {
        cout<<*(p1+i)<<endl;
    }
    return 0;
}

I want to allocate memory within a function and deallocate inside main().but this statement (delete p1) only delete a single element(doesn't delete entire block). i want to delete entire block.therefore , i think i need to use pointer to array but i'm unable to do with that(don't know how to return pointer to array). could you please modify my code according to that requirement ?

This is why we often use "smart pointers" to contain heap allocated objects. When the smart pointer goes out of scope, the contained object will be deleted automatically. There are caveats here, such as when something else takes a reference to the object managed by the "smart" pointer. I had to deal with this in the past. The solution wasn't simple, and basically required the design and development of a reference-counted garbage collector. It did work very well - in 10 million lines of code we had no explicit deletes and zero memory leaks.

The point I'm trying to make is that memory management and garbage collection are not trivial issues for anything other than trivial/simple applications that start, do something, and terminate. For long-running (in our case 24x365) applications, memory management becomes much more critical. At Nokia (my last employer) this was a serious issue, even with our Java servers. Java has automatic garbage collection / memory management, but it does have some problems that can cause severe system failures due to memory management if not directly addressed.

So, all this blather aside, getting to your issue.

  1. You allocate p1 with your allocate(n) function.
  2. You delete p1 in main().

Even though p1 was deleted, the memory that p1 was allocated is reusable, but the data is still available, hence your ability to access that data in your final loop since nothing else has been done that may overwrite that data. Remember, heap allocated data is not automatically removed from your program. Do some reading on the brk/sbrk functions. In any case, if you do another new or malloc operation, the memory will be reused.

could you please modify my code according to that requirement ?

You just do this:

delete[] p1;

Any memory allocated with new something[n]; must be deleted with delete[].

As for being able to access the memory after you deleted it, well, that's like rubberman explained. When freeing memory, the memory is still there, and it's not cleared or overwritten, it is simple marked as "free" to be reused in a future allocation. It is undefined behavior to try and access it again (although it usually works, it could crash or give you garbage).

If you are doing C-style allocations, then you can use alloca() which produces data that WILL go away when the function it was called in terminates. This is because the memory is allocated on the stack and not on the heap. If you are programming C++, then you can use this memory blob in a C++ new operator to create an object using this memory space. The major caveat here is that if the C++ object stays around after the function terminates, then it will be using unavailable memory (probably used by other stack data), and "bad things" will occur...

thanx for valuable replies.
but i want to send parameter(pointer to an array of n elements) and retun pointer to array and then delete it from main.

what syntax to write ?

Best thing here ...
really ...
is to use the STL vector container :)

For example ...

vector< int > fillVecFromFile( const string& FNAME )
{
   vector< int > v;
   v.reserve( 100 ); // or whatever best quess of file size
   ifstream fin( FNAME.c_str() )
   if( fin )
   {
      int tmp;
      while( fin > tmpInt ) v.push_back( tmpInt ); 
      fin.close();
   }
   else
      cout << "There was a problem opening file "
           << FNAME << endl;
   return v;
}

Or, maybe even better ...

bool fillVecFromFile( const string& FNAME, vector< int>& v )
{
   v.clear();
   v.reserve( 100 ); // or whatever best quess of file size
   ifstream fin( FNAME.c_str() )
   if( fin )
   {
      int tmp;
      while( fin > tmpInt ) v.push_back( tmpInt ); 
      fin.close();
      return true;
   }
   //else
  cout << "There was a problem opening file "
       << FNAME << endl;
  return false;
}

Or, maybe even better ...

Well, if we go into STL territory, we should do it in proper STL style ;)

template <typename OutputIter>
OutputIter fillFromFile(const std::string& FNAME, OutputIter it)
{
  typedef typename std::iterator_traits<OutputIter>::value_type Value;
  typedef std::istream_iterator<Value> InIter;
  std::ifstream fin( FNAME.c_str() )
  return std::copy(InIter(fin), InIter(), it);
}

and call it with:

std::vector<int> v;
fillFromFile("data.txt", std::back_inserter(v));

@ mike_2000_17 ... and your advanced approach would also allow speeds ups in reading data from very large files by ...

and call it with:

std::vector< int > v;
v.reserve( MY_LARGE_FILE_SIZE_BEST_GUESS_PLUS_SOME );
fillFromFile( FNAME, std::back_inserter(v) );
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.