1

Here's how I allocate it:

float** matrix = new float*[size];
for (int i = 0; i < size; i++) {
    matrix[i] = new float[size];
}

And here's how I deallocate:

if (matrix != nullptr) {
    for (int i = 0; i < size; i++) {
        delete[] matrix[i];
    }
}
free(matrix);

Is this correct or should I also delete[] the outer array?

naglas
  • 462
  • 1
  • 6
  • 16

2 Answers2

4

delete[] is always paired with a new[].

delete is always paired with a new.

So yes, in your case, you need to call delete[] matrix; to release the array of float* pointers. Don't use free unless that pointer has been obtained with a call to malloc &c., which would be unusual in C++.

Although, if you want to model a matrix in the mathematical sense then might I suggest you use a 3rd partly library. I use BLAS, part of the Boost distribution.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • Is there a difference between `delete[] matrix;` and `delete matrix[];`? – naglas Dec 12 '17 at 13:01
  • @CrasherX: Yes, the way I had it was a typo. Oops. – Bathsheba Dec 12 '17 at 13:02
  • `new`and `delete` themselves are "unusual in C++". – Vittorio Romeo Dec 12 '17 at 13:05
  • @VittorioRomeo: Which explains why I had the delete[] syntax incorrect in my first draft ;-) – Bathsheba Dec 12 '17 at 13:07
  • How is this getting so many upvotes? This is a [c++] question - mentioning that manual memory management is severely discouraged in C++ should be the first answer. Then you can go into how you should pair `new`/`delete` together if you really want to make your life difficult – Vittorio Romeo Dec 12 '17 at 13:10
  • Congrats, we have another "C++ developer" who now thinks that `float**`, `new`, and `delete` are the proper tools to create a 2D matrix... – Vittorio Romeo Dec 12 '17 at 13:11
  • @VittorioRomeo: Don't I cover that one off with my final paragraph? – Bathsheba Dec 12 '17 at 13:15
  • @VittorioRomeo That your coding style does not include the explicit use of `new` and `delete`, does not mean it's not proper C++. Other people have other preferences, and possible other contexts they need to take into account. – cmaster - reinstate monica Dec 12 '17 at 13:17
  • @cmaster: using `new`/`delete` in C++ is not about coding style, is about writing safe and correct code that makes use of RAII. If your C++ code is using `new`/`delete` when you could use a safer (potentially zero-cost) abstraction, it is **bad C++ code**. – Vittorio Romeo Dec 12 '17 at 13:19
  • @VittorioRomeo RAII *is* a programming style. A good one, for most of the code, no doubt. But it's just a style. There are other styles that can be used, with different trade-offs. You could, for instance, employ a reference counting scheme that does not rely on RAII. You could, for instance, avoid exceptions, which has many positive effects and which makes RAII much, much less important. The result can still be quite good C++ code. – cmaster - reinstate monica Dec 12 '17 at 13:28
  • @cmaster: saying that RAII is a programming style when describing C++ is a huge understatement. RAII is C++'s "killer feature" - it leads to safer code without additional overhead. Please stop misleading beginners - RAII exists for a reason: avoiding human mistakes related to resource acquisition and release. It is not a style, it's a solution to a big problem. – Vittorio Romeo Dec 12 '17 at 13:39
  • @VittorioRomeo RAII is only the "killer feature" that you believe it to be due to the existence of exceptions: RAII is the only means to ensure proper cleanup when any function you write may be aborted by third party code at any place. **And writing good C++ code does not imply using, or even allowing exceptions.** I disable exceptions in my projects, and thus find RAII much less impressive, it's certainly not a "killer feature" to me. I guess, this is very different in your projects. Which only goes to show that these are matters of style, after all. – cmaster - reinstate monica Dec 12 '17 at 14:26
  • @cmaster: you are completely wrong. I don't really like exceptions and love RAII. I personally do not use exceptions. If you cannot see the benefits of RAII unrelated to exceptions, you might want to review what RAII is and how ownership/scoping rules work in C++. – Vittorio Romeo Dec 12 '17 at 14:28
1

How to properly deallocate memory for a 2d array in C++?

Not manually. Use an abstraction like std::vector that deallocates memory for you thanks to RAII, or std::array if you know the size of your matrix at compile-time.

{
    std::vector<std::vector<float>> matrix(size);
    for(auto& v : matrix) v.resize(size);
}

// memory automatically freed at the end of the scope

You should almost never use new and delete in Modern C++. Refer to my answer here for more information: Malloc vs New for Primitives


If you are writing a program that requires an high-performance matrix implementation, please do not create your own. Your code and my example using std::vector both have a cache-unfriendly jagged layout which can severely harm performance. Consider using an high-quality production-ready library such as Eigen, Blaze, or BLAS instead.

Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
  • 2
    Never say never. There are still situations when using *std::vector* simply won't be fast enough. I can think of real-time signal processing being one such example (e.g real-time spectrogram display). – dsp_user Dec 12 '17 at 13:15
  • 3
    I don't think this is much better. Every time I see a jagged-edged construct modelling a matrix, I die a little inside. – Bathsheba Dec 12 '17 at 13:16
  • @Bathsheba: I don't disagree, but the question is not about optimal matrix memory layout. The question is about memory management, which is much more important to get right than cache friendliness for a beginner! – Vittorio Romeo Dec 12 '17 at 13:16
  • @dsp_user: sure, when you know what you're doing. Did you forget that the OP is a beginner who is asking help with pairing `new`/`delete` in C++? – Vittorio Romeo Dec 12 '17 at 13:18
  • 1
    Exactly. And how do you think that beginner may grow up to be a successful provider of some container class themselves if they are never taught not to mix `new[]` with `free()`? – cmaster - reinstate monica Dec 12 '17 at 13:21
  • @cmaster: a beginner should focus on learning the core concepts of the language first. RAII is much more important than `new`/`delete`! You don't need to know about those when we have `std::unique_ptr` or similar abstractions. `unique_ptr` should be taught before `new`/`delete`. – Vittorio Romeo Dec 12 '17 at 13:24
  • @cmaster: regardless, I am not saying that explaining how to correctly match `new`/`delete` is bad thing. I'm saying that the proper answer should start with saying **"don't do it in C++, use RAII instead"**, and **THEN** explain how to use `new`/`delete`. The accepted answer doesn't even mention `vector`, RAII, or `unique_ptr`! – Vittorio Romeo Dec 12 '17 at 13:25
  • @VittorioRomeo: But, with respect, this answer doesn't begin with "don't do it in C++, use RAII instead" either. But your answer to https://stackoverflow.com/questions/47773497/why-pass-by-const-reference-in-overload-operator-with-multiple-parameters is worth an upvote! – Bathsheba Dec 12 '17 at 13:32
  • Sorry, but I disagree. In my experience, one of the main drawbacks of current CS education is, that we are hiding the details behind the abstractions. You cannot fully understand your machine if you've never written assembler code. You cannot fully understand virtual dispatch if you've never implemented a vtable in C. You cannot fully understand RAII types if you've never used `new` explicitly. And without full understanding, you are bound to abuse the abstractions eventually. No doubt, abstractions are valuable. But good programmers need to understand when the abstractions start leaking. – cmaster - reinstate monica Dec 12 '17 at 13:35
  • @cmaster: I'm on the same page regarding "understanding abstraction". But I completely disagree with your conclusion. We should start by teaching beginners good and safe practices, **then** dive into their inner workings. What happened here is that the OP believes his code is safe and idiomatic, when it isn't. Do explain how `new`/`delete` work, but only **after** you show the proper way of dealing with memory management: RAII. – Vittorio Romeo Dec 12 '17 at 13:41
  • Ok, we seem to agree to disagree :-) – cmaster - reinstate monica Dec 12 '17 at 14:15