1

I'm trying to convert the a 1D array to a 2D array

nero
  • 25
  • 6

4 Answers4

3

If you want to allocate an actual 2D array, not an array of pointers, the syntax gets a little tricky:

int X = 16, Y = 8;
char (*pt)[X][Y] = malloc(X*Y);

Above, pt is a pointer to an X by Y array of chars. Because it's a pointer, accessing its elements requires an asterisk and parentheses, too:

for (int i = 0 ; i != X ; i++) {
    for (int j = 0 ; j != Y ; j++) {
        (*pt)[i][j] = (char)(i*X+j);
    }
}

Of course you need to free the pointer once you are done using the array:

free(pt);
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • wow.. i don't know this... I wonder what would be the syntax to pass this array as an argument.. thanks! – Titus Apr 25 '15 at 11:53
2

You need to allocate each row of the matrix separately:

unsigned char** index;

index = malloc(X * sizeof(unsigned char*)); // Allocate an array of pointers

for(int i = 0; i < X; i++)
    index[i] = malloc(Y * sizeof(unsigned char)) // Allocate each row

Refer also to this answer on malloc pointer casting.

Community
  • 1
  • 1
fede1024
  • 3,099
  • 18
  • 23
1

After your edit, it appears you are using C++.

In C++, you should prefer std::vector< std::vector< unsigned char > > for dynamic 2d array.

std::vector< std::vector< unsigned char > > index(X, std::vector<unsigned char>(Y));

Now you can use it as index[i][j] and it will be automatically cleaned, so need to free/delete explicitly.

Live demo here

Still if you want to allocate c-compliant arrays in conventional way, use

unsigned char** index;

try {
  index = new int*[X];
  for(int i = 0; i < X; ++i)
    index[i] = new int[Y];
} catch(...) {...}

For delete also you need to delete each element individually.


Old answer

unsigned char        **index;
index = malloc(X * sizeof *index);
if(!index) fail();
for(xi = 0; xi < X; ++xi) {
  index[xi] = malloc(Y * sizeof **index);
  if(!index[xi]) free_and_fail();
}

You first allocate space for X pointers and then in all X pointers you allocate one array.

While freeing the memory, you need to free each row individually:

if(index) for(xi = Y-1; xi >= 0; --xi) { /* xi is signed */
  free(index[xi];
}
free(index);
index = NULL;
Gyapti Jain
  • 4,056
  • 20
  • 40
1
unsigned char **index;
index = (unsigned char**)malloc( X*Y );

is wrong. index is an unsigned char**. You need to malloc two times to get a 2D array. If you want to allocate X rows, each with Y columns, use

unsigned char **index;
index = (unsigned char**)malloc( X * sizeof(unsigned char*) ); //Allocating number of rows
for(int i=0 ; i<X ; i++ ) 
{
    index[i] = (unsigned char*)malloc( Y * sizeof(unsigned char)); // Allocate each column
}

You should check if malloc does not fail. You should also free everything after its use to avoid a memory leak.

Spikatrix
  • 20,225
  • 7
  • 37
  • 83
  • I'm getting this error : a vlue of type "void*" cannot be assigned to a value of type "unsigned char*" – nero Apr 25 '15 at 11:44
  • 1
    The title of this question says that you compile in C. But, that error message can only come when you are compiling in C++. – Spikatrix Apr 25 '15 at 11:45