3

Which of the following is the correct way of doing it to avoid memory leaks?

//Option A
char* data = new char[4];
data = new char[5];
delete[] data;

//Option B
char* data = new char[4];
delete[] data;
data = new char[5];
delete[] data;
  • 2
    B. You should `delete` everything you `new`ed manually. – songyuanyao Jul 14 '16 at 03:41
  • Option A is a memory leak; the originally allocated memory is never destroyed since you don't know where that memory is after the pointer to it is overwritten with pointer to the 2nd allocation. As written, the `delete` in Option A deletes the 2nd allocation. Use `unique_ptr` or `shared_ptr`. – mkal Jul 14 '16 at 03:46
  • 1
    Answer section is below, guys. – Benjamin Lindley Jul 14 '16 at 03:48
  • may below link help you [link](http://www.programmerinterview.com/index.php/c-cplusplus/what-is-a-memory-leak-in-c/) – Dipak Prajapati Jul 14 '16 at 03:48
  • You don't necessarily *need* to do the `delete`. The need to do so emanates from the impact of the leak. If the program is short-lived and doesn't allocate a lot of memory, and the OS cleans up memory reliably, then it can be acceptable to not worry bout freeing memory and in fact it reduces the risk of introducing a bug caused by inappropriate freeing. – Kaz Jul 14 '16 at 05:01

1 Answers1

5

You have clear memory leak in option A. Let's say you have allocated memory for new char[4]; at some memory location 0x7256AC7D and data points to this location. Then without deleting this you have allocated another memory location for new char[5]; and data points to this new location. Now you have no pointer to old location 0x7256AC7D and have no way to delete that. So you are leaking that memory.

In other notes, it's better or easier to use std::shared_ptr or std::unique_ptr from C++11 to avoid this kind of leaks.

taskinoor
  • 45,586
  • 12
  • 116
  • 142
  • I would insert "**often** better / easier" Sometimes you work with platforms that don't support c++11, or your application needs lower overhead. I would, however, generally recommend using it when possible as it's one of the lightest features of c++11 and can save a lot of headache. – Assimilater Jul 14 '16 at 03:52
  • Even better to use `std::vector` from C++98, if you are allocating an array. – Benjamin Lindley Jul 14 '16 at 03:52
  • @BenjaminLindley `std::vector` won't be immune from this type of leak. You can generate memory leaks in same way with `std::vector` too. – taskinoor Jul 14 '16 at 03:55
  • 1
    @Assimilater: The important point about that comment is `std::vector`, not the fact that it is available in C++98. – Benjamin Lindley Jul 14 '16 at 03:55
  • 1
    @taskinoor: Explain how. It's much easier to generate a memory leak using a smart pointer than `std::vector`. Smart pointers have release functions, `std::vector` does not. – Benjamin Lindley Jul 14 '16 at 03:56
  • So in terms of performance should I use a vector or a shared_ptr or a unique_ptr? – Mr. Fahrenheit Jul 14 '16 at 03:57
  • @BenjaminLindley if you `new` a `std::vector` and then reassign the pointer to another `std::vector` without deleting the first like OP posted then it will be a leak, right? I think that is the main question OP is having - whether you need to delete any thing before re-assigning the pointer. The question is not about array in particular, I guess. – taskinoor Jul 14 '16 at 03:59
  • @Mr.Fahrenheit performance isn't really the question between those three, it's about functionality. `std::vector` is designed for arrays, `std::shared_ptr` and `std::unique_ptr` are designed for elements. Use `std::unique_ptr` if you don't plan on passing the pointer around to other functions. – Assimilater Jul 14 '16 at 04:00
  • 1
    @taskinoor: Well you'd have the same problem if you `new` a smart pointer. But why would you do either of those things? – Benjamin Lindley Jul 14 '16 at 04:01
  • @BenjaminLindley how I would have the same problem with smart pointer? If I have `std::shared_ptr a = std::make_shared(SomeThing)` and then do `a = std::make_shared` then old one is supposed to be deleted without causing any leak. Isn't it? – taskinoor Jul 14 '16 at 04:04
  • 1
    @taskinoor you're not comparing apples to apples. What you were suggesting for `std::vector` would be **like** doing `std::shared_ptr *a = new std::shared_ptr(new thing())`. Benjamin was talking about `std::vector data(5);` with no `new` keyword – Assimilater Jul 14 '16 at 04:06
  • @Assimilater is `std::shared_ptr *a = new std::shared_ptr(new thing())` common practice while working with smart pointers? Just asking since I haven't seen code like that yet. If you choose to use smart pointer then you will use them as they are supposed be used, right? – taskinoor Jul 14 '16 at 04:10
  • 1
    @taskinoor: No, it's not common practice. But neither is this: `std::vector* a = new std::vector;` -- Which I was not suggesting doing. – Benjamin Lindley Jul 14 '16 at 04:11
  • @taskinoor your earlier comment: "if you `new` a `std::vector` and then reassign the pointer to another `std::vector`" – Assimilater Jul 14 '16 at 04:15
  • @BenjaminLindley well, I think before the introduction of `std::move` it was pretty common to return a pointer to vector. And also passing a pointer to vector in a function. Yes, in both cases you can (and probably should) use reference, but I guess many people just like to stick with old pointers (without much reference). – taskinoor Jul 14 '16 at 04:15
  • 1
    @taskinoor: Huh? When did we start talking about returning values? And anyway, this is all in reference to your answer, which recommends C++11 smart pointers. So if those are available, then so are move semantics. – Benjamin Lindley Jul 14 '16 at 04:21
  • @Assimilater, `new` doesn't allocate on stack. Anyway, I got the point that you and @BenjaminLindley are trying to make. But as I said in one of my previous comment this question is not about array or vector in particular, rather with any type. So it seems that we have gone too far in the comments here :-). Probably there can be a separate discussion with a broader spectrum. So I'm quitting here. Thanks for your comments and discussion. – taskinoor Jul 14 '16 at 04:24
  • @taskinoor Your right, this discussion is getting long, but it is about a (somewhat minor, but important) issue with your answer. The OP was indeed about `new`/`delete` in general and in general dynamic memory implies using smart pointers. But the example was dynamically allocating *arrays* so a **vector** is more appropriate. (PS I mentioned stack allocation because you mentioned returning a pointer and I can't imagine anyone trying to return a pointer to a dynamically allocated vector....but I can imagine a novice trying to return a pointer to a statically allocated one) – Assimilater Jul 14 '16 at 04:29
  • @taskinoor related [SO Question (see both answers)](http://stackoverflow.com/questions/13061979/shared-ptr-to-an-array-should-it-be-used). The point is your answer should show not tell because using shared_ptr with an array has its quirks. – Assimilater Jul 14 '16 at 04:33