0

How can I initialize a floating or unsigned multidimensional dynamic array in C++?

I tried the following and got a seg fault,

float **array = NULL:

array = new float* [rows];
for(unsigned int i = 0; i < rows; ++i)
{
    array[i] = new float [cols];
}

Thanks in advance.

onie
  • 13
  • 4
  • 5
    There isn't enough code there to diagnose the problem. Please post a [mcve]. – R Sahu Mar 12 '18 at 21:19
  • please show at least where you write something into the array (and eliminate the duplicate definition of array) – Stephan Lechner Mar 12 '18 at 21:20
  • @onie I'd go ahead and say that you should really use a vector or similar abstraction. It will save you many headaches. – Javier Martín Mar 12 '18 at 21:22
  • Use a one-dimensional array (`std::vector`) and stay away from `new` and `float**`. – tadman Mar 12 '18 at 21:23
  • 1
    `std::vector array(rows * cols);` or if you really don't want to abstract it `std::vector> array(rows, std::vector(cols));` – NathanOliver Mar 12 '18 at 21:24
  • 1
    `float **array = NULL:` followed by `float** array = new float* [rows];` looks like you might be having a [Variable Shadowing](https://en.wikipedia.org/wiki/Variable_shadowing) problem. No way to be sure, though, without the aforementioned MCVE. – user4581301 Mar 12 '18 at 21:44
  • Possible duplicate of [Declaring a pointer to multidimensional array and allocating the array](https://stackoverflow.com/questions/3904224/declaring-a-pointer-to-multidimensional-array-and-allocating-the-array) – Francis Cugler Mar 12 '18 at 23:16

2 Answers2

0

I voted to close this as a duplicate of Declaring a pointer to multidimensional array and allocating the array

When declaring a multi-dimensional array arrary[col][rows], [col] needs to be constant where [rows] doesn't have to be. This notation should work to resolve the issue.

const int col = someval;
const int row = someval;

int (*array)[row] = new int[col][row];

Otherwise you can use a single dimensionally array such that it has [row*col] elements. From there you would have to do the calculation when indexing the flat array for a 2D structure.

Typically a single array and double for looping would look like this:

type *array = new type[row * col];

for ( int i = 0; i < row; i++ ) {
    for ( int j = 0; j < col; j++ ) {
        array[i * col + j];
    }
}

This should help.

Francis Cugler
  • 7,788
  • 2
  • 28
  • 59
0

You can allocate in a fairly traditional manner for a given number of pointers and and then a given number of float assigning a pointer to each allocated block of float using the new expression and then using a corresponding delete expression to regain the memory allocated to avoid a memory leak when that allocated memory is no longer needed. It is loosely analogous to using malloc and free, but there is a large difference in what goes on under the hood.

For example, given your pointer-to-pointer-to-float, you could construct a short example to illustrate:

#include <iostream>
#include <iomanip>

using namespace std;

#define ROWS 10
#define COLS 10

int main (void) {

    float **array = NULL;               /* pointer to pointer to float */

    array = new float*[ROWS];           /* allocate ROWS pointers to float */
    for (int i = 0; i < ROWS; i++) {
        array[i] = new float[COLS];     /* allocate COLS floats */
        for (int j = 0; j < COLS; j++)
            array[i][j] = (i + 1) * (j + 1);
    }

    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++)
            cout << setw(4) << array[i][j];
        cout << "\n";
        delete[] array[i];              /* delete COLS floats */
    }
    delete[] array;                     /* delete ROWS pointers to float */
}

Example Use/Output

$ ./bin/array_new_del
   1   2   3   4   5   6   7   8   9  10
   2   4   6   8  10  12  14  16  18  20
   3   6   9  12  15  18  21  24  27  30
   4   8  12  16  20  24  28  32  36  40
   5  10  15  20  25  30  35  40  45  50
   6  12  18  24  30  36  42  48  54  60
   7  14  21  28  35  42  49  56  63  70
   8  16  24  32  40  48  56  64  72  80
   9  18  27  36  45  54  63  72  81  90
  10  20  30  40  50  60  70  80  90 100

You must take care to always preserve a pointer to the memory you allocate and to delete the memory you allocate when it is no longer needed to prevent leaking memory. It is also imperative that you run your code that allocates and deletes memory through a memory error checking program to insure you have used the memory correctly and that all memory has been freed when it is no longer needed. For Linux, valgrind is the normal choice. All you need to it is run your code through it, e.g.

$ valgrind ./bin/array_new_del
==1206== Memcheck, a memory error detector
==1206== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1206== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==1206== Command: ./bin/array_new_del
==1206==
   1   2   3   4   5   6   7   8   9  10
   2   4   6   8  10  12  14  16  18  20
   3   6   9  12  15  18  21  24  27  30
   4   8  12  16  20  24  28  32  36  40
   5  10  15  20  25  30  35  40  45  50
   6  12  18  24  30  36  42  48  54  60
   7  14  21  28  35  42  49  56  63  70
   8  16  24  32  40  48  56  64  72  80
   9  18  27  36  45  54  63  72  81  90
  10  20  30  40  50  60  70  80  90 100
==1206==
==1206== HEAP SUMMARY:
==1206==     in use at exit: 0 bytes in 0 blocks
==1206==   total heap usage: 13 allocs, 13 frees, 74,208 bytes allocated
==1206==
==1206== All heap blocks were freed -- no leaks are possible
==1206==
==1206== For counts of detected and suppressed errors, rerun with: -v
==1206== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Always verify that you have freed all memory you allocate and that there are no memory errors.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85