37323

Should I delete pointers that come from other functions or class methods?

Question:

I have a background in Java and I'm still not fully used to the concept of pointers and scope, so sorry if the question seems silly.

I read somewhere that I should delete pointers that I have allocated on the Heap. I understand that but should I also delete a pointer that is given to me like this:

#include<dirent.h> DIR* dir; struct dirent* entries; dir= opendir("D:/DIR") entries= readdir(entries) // Should I delete the pointers after I'm done with them? delete entries; delete dir;

Should I delete the pointers which are assigned from somewhere else or just going out of scope deletes them automatically?

Or is it even right to delete them since I haven't assigned them using new? But then if it's wrong how can I make sure that the memory assigned from the other methods would be deleted after I'm finished using them?

Answer1:

C is not the same as C++, notably for this aspect.

When using some external C (or C++) function provided by some external library, you should <strong>read its documentation</strong> and <strong>follow</strong> the "ownership" rules and <strong><em>conventions</em></strong>. For example if you use <a href="http://man7.org/linux/man-pages/man3/getline.3.html" rel="nofollow">getline</a> you understand that you need to free like <a href="https://stackoverflow.com/a/25313892/841108" rel="nofollow">here</a>. If you use <a href="http://man7.org/linux/man-pages/man3/opendir.3.html" rel="nofollow">opendir</a> you should use <a href="http://man7.org/linux/man-pages/man3/closedir.3.html" rel="nofollow">closedir</a>. If you use <a href="https://www.sqlite.org/c3ref/prepare.html" rel="nofollow">sqlite3_prepare_v2</a> you'll need to <a href="https://www.sqlite.org/c3ref/finalize.html" rel="nofollow">sqlite3_finalize</a> it, etc... Sometimes you'll think in terms of some <a href="https://en.wikipedia.org/wiki/Abstract_data_type" rel="nofollow">abstract data type</a> (like <a href="https://stackoverflow.com/a/47235897/841108" rel="nofollow">here</a>) with a <a href="https://en.wikipedia.org/wiki/Destructor_(computer_programming)" rel="nofollow">destructor</a>-like function.

When you <em>develop</em> your own (public or "private") function in C, you need to <em>document</em> if it returns heap allocated memory and who (and how) is responsible of free (or releasing) it.

With C++, you also have <a href="http://en.cppreference.com/w/cpp/memory" rel="nofollow">smart pointers</a> and <a href="https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization" rel="nofollow">RAII</a>; so you generally can avoid manual new and delete. Smart pointers are helpful, but <a href="https://en.wikipedia.org/wiki/No_Silver_Bullet" rel="nofollow">not a silver bullet</a>.

So <strong>you should <em>explicit</em> and <em>document</em> conventions</strong> (and follow the conventions of external libraries and APIs) about ownership. Understanding and defining wisely such conventions is an important task.

<a href="https://en.wikipedia.org/wiki/Circular_reference" rel="nofollow">Circular references</a> are difficult to handle (consider <a href="https://en.wikipedia.org/wiki/Weak_reference" rel="nofollow">weak pointers</a> when applicable). I recommend reading about garbage collection concepts and techniques (e.g. the <a href="http://gchandbook.org/" rel="nofollow"><em>GC handbook</em></a>), to at least be able to name appropriately your approaches and understand the limitations and power of <a href="https://en.wikipedia.org/wiki/Reference_counting" rel="nofollow">reference counting</a>. In <em>some</em> cases, you might even explicitly use a <a href="https://stackoverflow.com/a/7909164/841108" rel="nofollow">garbage collector library</a> or code your own allocator.

<a href="https://en.wikipedia.org/wiki/Manual_memory_management" rel="nofollow">Manual memory management</a> is a whole program property, and that is why it is hard. There are even cases (long-living processes doing a lot of allocation) where you need to be afraid of <a href="https://en.wikipedia.org/wiki/Fragmentation_(computing)" rel="nofollow">fragmentation</a>.

Tools like <a href="http://valgrind.org/" rel="nofollow">valgrind</a> and the <a href="https://en.wikipedia.org/wiki/AddressSanitizer" rel="nofollow">address sanitizer</a> (with <a href="http://gcc.gnu.org/" rel="nofollow">GCC</a>'s <a href="https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html" rel="nofollow">instrumentation options</a> or <a href="http://clang.llvm.org/" rel="nofollow">Clang</a>'s ones) are practically very helpful to hunt <a href="https://en.wikipedia.org/wiki/Memory_leak" rel="nofollow">memory leaks</a> and some other memory bugs. Be also aware of <a href="https://en.wikipedia.org/wiki/Address_space_layout_randomization" rel="nofollow">ASLR</a>. Take care to understand the <a href="https://en.wikipedia.org/wiki/Virtual_address_space" rel="nofollow">virtual address space</a> of your <a href="https://en.wikipedia.org/wiki/Process_(computing)" rel="nofollow">process</a>. On Linux, read <a href="http://man7.org/linux/man-pages/man5/proc.5.html" rel="nofollow">proc(5)</a> then try cat /proc/$$/maps and cat /proc/self/maps in some terminal for a useful insight.

Answer2:

Not necessarily.

The unavoidable rule in C++ is that every new needs to be paired with a delete, and every new[] with a delete[], and that malloc, free, &c. are still available.

So it's tempting to suppose that the memory you get back from readdir is required to be released with an explicit call to delete, but that <em>might</em> not be the case:

<ol><li>

It might have been allocated with a new[], or even, malloc!

</li> <li>

The library might provide a function that you need to call that releases the memory.

</li> <li>

If the library has a persuasion to working well with the C++ standard library, it might provide you with a <em>deleter</em>: which you can pass on construction to a <em>smart pointer</em> such as std::unique_ptr.

</li> </ol>

I think that (2) is most likely and is the most sensible since different C++ runtime environments might perform new and delete differently. (3) is an extension to this concept and if they support it then use that.

The golden rule is to <strong>check the documentation</strong> and do what it tells you.

Answer3:

There's no definitive answer to the question, because it <em>always</em> depends on the semantics by which the memory was allocated. For example in the very code example you gave, you <em>must</em> not use delete for deallocation, because opendir is not a C++ function (but a POSIX one) and to properly close it you call closedir. The pointer itself then can be discarded (no deletion requierd, closedir internally does the cleanup). Just make sure you don't use it after free (see: use-after-free-bug).

In general you always have to consult the manual of the function that gives you a pointer, where it's also specified exactly how to deallocate it.

Just to give you the idea:

<ul><li>

malloc/calloc/realloc → free

</li> <li>

fopen → fclose

</li> <li>

X… → XFree

</li> </ul>

Answer4:

Ultimately you should consult the vendor's manual and see if their functions do the cleaning themselves or you need to call another function to do the cleaning etc. In general when talking about <em>raw</em> pointers in C++ you should explicitly release the allocated memory where appropriate. Whether it comes from a function or a new / new[] operator does not make a difference. To avoid this new / delete combination you can utilize <a href="http://en.cppreference.com/w/cpp/header/memory" rel="nofollow">smart pointers</a> and the <a href="http://en.cppreference.com/w/cpp/language/raii" rel="nofollow">RAII</a> technique.

Recommend

  • Redshift Performance of Flat Tables Vs Dimension and Facts
  • Repeat the rows in a data frame based on values in a specific column [duplicate]
  • How to move double in %rax into particular qword position on %ymm or %zmm? (Kaby Lake or later)
  • Change only the image inside same div when option from dropdown is chosen
  • ListBox does not display the binding data
  • Why is release often called shortly after a local var is used instead of just autoreleasing
  • Writing CSV in perl
  • SLF4J - What is a dangling or detached marker?
  • Google Chart: How to draw the vertical line for bar graph
  • What caused hibernate generate a update clause?
  • BeautifulSoup: Can't convert NavigableString to string
  • Use query params of parent route to refresh the model in subroute
  • Get rendered html code in Backing Component from Composite Component
  • reset jquery smartwizard
  • record audio in HTML / js without Flash?
  • include dlls in visual studio c++ 2008
  • Tools for understanding HTML layout
  • react split panel resize
  • Can you pass an array from javascript to asp.net mvc controller action without using a form?
  • Where these are stored?
  • Implement JwtBearer Authentication in NSwag SwaggerUi
  • MySQL performance when updating row with FK
  • Access user's phone number on iOS 7
  • How to explicitly/implicitly implemented interface members in C++/CLI?
  • CSS bleed-through with cfinput type=“datefield”
  • how do i write assembly code from c#?
  • DIV instruction jumping to random location?
  • converting text file into xml using php?
  • Diff between two dataframes in pandas
  • uniform generation of points on 3D box
  • Unable to get column index with table.getColumn method using custom table Model
  • Moving Android View and preventing onDraw to be called over and over again
  • xtable package: Skipping some rows in the output
  • custom UITableViewCell with image for highlighting
  • Cancel a live stream “fast motion” catch-up in Flash
  • How to add a column to a Pandas dataframe made of arrays of the n-preceding values of another column
  • Timeout for blocking function call, i.e., how to stop waiting for user input after X seconds?
  • Traverse Array and Display in markup
  • python regex in pyparsing
  • How does Linux kernel interrupt the application?