1

I need to declare a dynamically allocated 2 dimensional array, in a header, without knowing its dimensions, which will be established inside a function.

In the header I want to place:

#define MAX_BARS_ALLOWED 20000
extern int Gregorian[][MAX_LINES_ALLOWED];  //it works

and in the .cpp file, inside a function:

int **Gregorian=new int*[NumLastItem+1][MAX_LINES_ALLOWED];  //this does NOT work, why ?

... and since I initialize it inside a function, will it be really global.

Can anyone teach me the correct way to do this ? Thank you in advance !!

JNF
  • 3,696
  • 3
  • 31
  • 64
alwaystudent
  • 173
  • 1
  • 2
  • 11

3 Answers3

0

This is my favorite method to declare a variable-sized matrix on the heap : You allocate a extra elem at the end of every row in order to know where the boundary is (it kinda like C-style string).

int** read_matrix(int size_x, int size_y)
{
    int** matrix;
    matrix = calloc(size_x, 1+sizeof(int*)); // alloc one extra ptr
    for(int i = 0;i<size_x;i++) {
        matrix[i] = calloc(size_y, sizeof(int));
    }
    matrix[size_x] = NULL; // set the extra ptr to NULL

    /* populate the matrix if needed
    for(int i = 0;i<size_x;i++) {
        for(int j = 0;j<size_y;j++) {
            matrix[i][j] = i*10+j;
        }
    }
    */
    return matrix;
}

// keep looping until you find the NULL one
for( int i=0; first_matrix[i] != NULL; i++ ) {
    free( first_matrix[i] );
}
free( first_matrix );

This snippet was copied from there : int matrix with pointers in C - memory allocation confusion

Usage:

in the header :

#define MAX_BARS_ALLOWED 2000
extern int** Gregorian;

in the cpp:

Gregorian = read_matrix(NumLastItem+1,MAX_LINES_ALLOWED);
Community
  • 1
  • 1
lucasg
  • 10,734
  • 4
  • 35
  • 57
  • no, it is not a variable size matrix where I must add elements. I want to : declare it as global in the header and, once inside the function, the function calculates its first dimension once and for all and initializes it ( Solution 1 ). Is it possible to do it ? Yes, alternatively I could declare it in the header and in the file .cpp with false dimensions and then resize it inside the function ( Solution 2 ) but first I would like to learn if it is possible to have SOlution 1 working. Thanks anyway – alwaystudent May 22 '13 at 09:48
  • @ georgesl thanks for the answer but, just to complete my education on the subject, what should I do to resize a 2 dimensional array already declared and dinamically allocated ? – alwaystudent May 23 '13 at 19:57
  • @alwaysstudent : that's are real pain to resize a dynamically allocated matrix (you can't just realloc like any 1D array because it will overwrite values of the next row). To do so, you have to malloc the new array, copy the values from the old to the new and modify every pointers to point towards the new array. Better use STL containers like vector, valarray or Boost::Matrix – lucasg May 24 '13 at 07:40
0

If you create new Instance with same name of array inside function it override and hide upper one. You can allocate external array, but dont create new variable with same name.

Martin Perry
  • 9,232
  • 8
  • 46
  • 114
-1

In your header file have a special definition for the implementation source. Like this:

#ifndef ARRAY_HEADER_HPP
#define ARRAY_HEADER_HPP 1

#ifdef ARRAY_IMPL
#define extern // remove extern for implementation
#endif

#define MAX_LINES_ALLOWED 20000
extern int **Georgian;

#ifdef ARRAY_IMPL
#undef extern
#endif

#endif // ARRAY_HEADER_HPP

Then where you assign the array you include the header like this

#define ARRAY_IMPL
#include "array_header.hpp"

void alloc_array(){
    Georgian = new int*[var+1];
    for(size_t n = 0; n < (var+1); n++)
        Georgian[n] = new int[MAX_LINES_ALLOWED];
}

void dealloc_array(){
    for(size_t n = 0; n < (var+1); n++)
        delete[] Georgian[n];
    delete[] Georgian;
}
RamblingMad
  • 5,332
  • 2
  • 24
  • 48