4

If you apply "delete" instead of "delete[]" to an array in C++, then you will create a memory leak because only the first element will be deleted. But what happens if you apply "delete[]" to a non-array pointer by accident? For instance (just a toy example):

   class X {   
      void  foo()
      {
          X* x = new X();
          delete[] x; // What happens here?
      }
   };

Can it do any harm? And if so, what harm?

Paul Jansen
  • 1,216
  • 1
  • 13
  • 35

2 Answers2

1

If you apply "delete" instead of "delete[]" to an array in C++, then you will create a memory leak because only the first element will be deleted.

That is not always true. Because new, new[], delete, delete[] operators can also be overloaded, using delete instead of delete[] (or the other way around) can make a huge difference.

Also, some compilers use the over-allocation technique described here. Therefore applying delete[] on a non-array pointer causes undefined behavior.

Călin
  • 347
  • 2
  • 13
  • Overallocation is not the reason for undefined behavior. Applying delete[] to a non-array pointer itself is. – kraskevich Jan 04 '15 at 23:06
  • First, the problem has nothing to do with overloading. And second, mismatching the type of `new` and `delete` is undefined behavior, and will in practice cause real problems with practically every existing compiler. – James Kanze Jan 05 '15 at 01:37
1

If you use a simple delete where a delete[] is required, you do not have a memory leak, you have undefined behavior. In a lot of cases, you will corrupt the free space arena, leading to a later program crash, but of course, undefined behavior is undefined, so anything may happen.

Using delete[] where a simple delete is required is also undefined behavior; in practice, it too will often lead to corrupting the free space arena, or other ugly results.

Of course, in practice, there is no context I can think of where you would use an array new, so you can pretty much forget about delete[].

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • 1
    And even when you do use array new, it should be in the context of initializing a `std::unique_ptr` or similar smart pointer, which will take care of calling `delete[]` automatically. – Ben Voigt Jan 05 '15 at 01:39
  • @BenVoigt Maybe, but in what context? `std::unique_ptr` isn't a panacea, and will usually behave exactly like `std::vector`. Presumable, if you are allocating, it's because you need to copy it, and copying the `std::vector` is too expensive. (In this case, `std::shared_pr` is likely appropriate.) – James Kanze Jan 05 '15 at 12:29
  • `std::vector` gets overused, because for decades it was the only standard smart pointer for managing an array. But often you don't need resizing or bulk copy, and in such cases `std::unique_ptr` is a better fit for the task. "Presumable, if you are allocating, it's because you need to copy it"... No, I find that it is usually because the size is not fixed at compile time. – Ben Voigt Jan 05 '15 at 15:16
  • @BenVoigt `std::vector` works perfectly well if the size isn't known at compile time. The only time you might want to not use it is because you need shallow copy (with all of the problems that implies) for performance reasons. And I fail to see when `std::unique_ptr` would be a better fit: You loose the length information, and you can't get a debugging version with bounds checking. – James Kanze Jan 05 '15 at 22:52
  • consider storing a matrix. The number of rows and columns are already separately stored, so the length information in the vector is too verbose (separate size and capacity), redundant, and useless (because total length cannot be used to validate column or row indexes or linearize offset) – Ben Voigt Jan 05 '15 at 23:41