malloc a 2D array

M

mike79

Hey all,

Im use to using malloc() with a one-dimensional array. But I have
found the need to use a 2D array, and would like to confirm whether I
am allocating memory correctly.

As I can gather, unlike a 1D array, you cannot allocate memory to a 2D
array with only 1 line of code.

Just say i wish to have an array of strings, I wish to declare an
array like arrayString[10][20], where I will be able to hold 10
strings, each string of a maximum of 20 characters (as an example).

Can I do this?

************************************
arrayString = malloc(10);

int i;
for (i = 0; i< 10; i++)
{
arrayString = malloc(20);
}
************************************

Would this be ideal, or is there a better solution to this problem?

Thank you all for your help.. Much appreciated!
mike79
 
T

Tom Zych

mike79 said:
Im use to using malloc() with a one-dimensional array. But I have
found the need to use a 2D array, and would like to confirm whether I
am allocating memory correctly.
As I can gather, unlike a 1D array, you cannot allocate memory to a 2D
array with only 1 line of code.

Depends how you do it.
Just say i wish to have an array of strings, I wish to declare an
array like arrayString[10][20], where I will be able to hold 10
strings, each string of a maximum of 20 characters (as an example).

For consistency with your code I will assume you mean 19 characters
plus the terminating \0.
Can I do this?
************************************
arrayString = malloc(10);

int i;
for (i = 0; i< 10; i++)
{
arrayString = malloc(20);
}
************************************


arrayString is an array of pointers to char. Hence:
char **arrayString;
arrayString = malloc(10 * sizeof (char *));

Usual caveats about checking the return value from malloc apply.

This way requires a loop to allocate, but allows the usual
arrayString[j] usage.
Would this be ideal, or is there a better solution to this problem?

If you want to avoid the loop, you can just make arrayString a
pointer to char, malloc(10*20), and do pointer arithmetic. I'd say
the loop is easier all around.
 
K

Kevin Easton

mike79 said:
Hey all,

Im use to using malloc() with a one-dimensional array. But I have
found the need to use a 2D array, and would like to confirm whether I
am allocating memory correctly.

As I can gather, unlike a 1D array, you cannot allocate memory to a 2D
array with only 1 line of code.

Just say i wish to have an array of strings, I wish to declare an
array like arrayString[10][20], where I will be able to hold 10
strings, each string of a maximum of 20 characters (as an example).

Can I do this?

************************************
arrayString = malloc(10);

Nope. arrayString should be declared as:

char **arrayString;

and so your malloc is allocating space for 10 (char *)s, not 10 chars:

arrayString = malloc(10 * sizeof *arrayString);
int i;
for (i = 0; i< 10; i++)
{
arrayString = malloc(20);
}
************************************

Would this be ideal, or is there a better solution to this problem?


If the size of strings is known at compile-time, and you aren't going to
be swapping strings around inside the array, this is probably better:

char (*arrayString)[20];

arrayString = malloc(10 * sizeof *arrayString);

.... that's it.

There are some more methods in the comp.lang.c FAQ.

- Kevin.
 
P

pete

mike79 said:
Hey all,

Im use to using malloc() with a one-dimensional array. But I have
found the need to use a 2D array, and would like to confirm whether I
am allocating memory correctly.

As I can gather, unlike a 1D array, you cannot allocate memory to a 2D
array with only 1 line of code.

Just say i wish to have an array of strings, I wish to declare an
array like arrayString[10][20], where I will be able to hold 10
strings, each string of a maximum of 20 characters (as an example).

/*
** Make a pointer to the first element of the two dimensional array:
** char (*arrayString_ptr)[20];
** arrayString_ptr = malloc(10 * sizeof *arrayString_ptr);
*/

/* BEGIN new.c */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void)
{
char *number[] = {"one","two","three","four","five","six",
"seven","eight","nine","ten"};
char (*arrayString_ptr)[20];
int word;

arrayString_ptr = malloc(10 * sizeof *arrayString_ptr);
if (!arrayString_ptr) {
fputs("I'm tired.\n", stderr);
exit(EXIT_FAILURE);
}
for (word = 0; word != 10; ++word) {
strcpy(arrayString_ptr[word], number[word]);
}
for (word = 0; word != 10; ++word) {
puts(arrayString_ptr[word]);
}
free(arrayString_ptr);
return 0;
}

/* END new.c */
 
T

Tom Zych

Kevin said:
arrayString = malloc(10 * sizeof *arrayString);

Whoops, my bad. I knew better, too. Do it this way, not the way I
wrote it.
If the size of strings is known at compile-time, and you aren't going to
be swapping strings around inside the array, this is probably better:
char (*arrayString)[20];
arrayString = malloc(10 * sizeof *arrayString);

Perhaps it's just unfamiliarity, but I find this hard to understand.
I think the malloc-twice way is much more intuitive. Opinions?
 
T

Tom Zych

pete said:
char *number[] = {"one","two","three","four","five","six",
"seven","eight","nine","ten"};

A C programmer who starts counting at one. How unusual... :)
 
Joined
Jan 23, 2009
Messages
1
Reaction score
0
Here's how you dynamically allocate memory for a 2D array.
Presented in matrix[col][row] format:
Iterating through its columns moves in the x direction.
Iterating through its rows moves in the y direction.

Code:
[COLOR="DarkGreen"]/* Written by Vincent Garcia::Undergrad::UCSB.*/[/COLOR]


[COLOR="DarkGreen"]/* This is your 2D array. */[/COLOR]
[COLOR="Blue"]double[/COLOR]** matrix;
[COLOR="DarkGreen"]/* The size dimensions of your 2D array. */[/COLOR]
[COLOR="Blue"]int[/COLOR] numRows, numCols;
[COLOR="DarkGreen"]/* Used as indexes as in matrix[x][y]; */[/COLOR]
[COLOR="Blue"]int[/COLOR] x, y; 
[COLOR="DarkGreen"]/*
 * Get values into numRows and numCols somehow.
 */[/COLOR]


[COLOR="DarkGreen"]/* Allocate pointer memory for the first dimension of a matrix[][]; */[/COLOR]
matrix = ([COLOR="Blue"]double[/COLOR] **) [COLOR="Blue"]malloc[/COLOR](numCols * [COLOR="Blue"]sizeof[/COLOR]([COLOR="Blue"]double[/COLOR] *));
if([COLOR="Blue"]NULL[/COLOR] == matrix){[COLOR="Blue"]free[/COLOR](matrix); [COLOR="Blue"]printf[/COLOR]("Memory allocation failed while allocating for matrix[].\n"); [COLOR="Blue"]exit[/COLOR](-1);}

[COLOR="DarkGreen"]/* Allocate integer memory for the second dimension of a matrix[][]; */[/COLOR]
for(x = 0; x < numCols; x++)
{
    matrix[x] = ([COLOR="Blue"]double[/COLOR] *) [COLOR="Blue"]malloc[/COLOR](numRows * [COLOR="Blue"]sizeof[/COLOR]([COLOR="Blue"]double[/COLOR]));
    if([COLOR="Blue"]NULL[/COLOR] == matrix[x]){[COLOR="Blue"]free[/COLOR](matrix[x]); [COLOR="Blue"]printf[/COLOR]("Memory allocation failed while allocating for matrix[x][].\n"); [COLOR="Blue"]exit[/COLOR](-1);}
}


[COLOR="DarkGreen"]/* Iterate through matrix (thru-row-first). */
/* Initialize matrix to be filled with 0's. */[/COLOR]
for(y = 0; y < numRows; i++)
    for(x = 0; x < numCols; j++)
        matrix[x][y] = 0;


[COLOR="DarkGreen"]/* Deallocate memory of 2D array. */[/COLOR]
for(x = 0; x < numCols; x++)
    [COLOR="Blue"]free[/COLOR](matrix[x]);
[COLOR="Blue"]free[/COLOR](matrix);
 
Joined
May 14, 2009
Messages
1
Reaction score
0
Thank you very much vincetg2 for the clear solution. It was quite usefull for me. I modified your code a little bit, perhaps this will be usefull for another one. I'm not a C expert,So if you have any sugegestions about the code, please post a reply. I think, this is the right way to create a 2D array by a function. It seems to work for me, but perhaps I overlooked something? Thanks again for the snippet, anyway.

Code:
char** create_2D_char_array( int numrows, int numcols){
	char **data;
	data = (char **) malloc(numrows * sizeof(char *));
	if(data == NULL){
		free(data);
		printf("Memory allocation failed while allocating for dim[].\n");
		exit(-1);
	}
	//
	/* Allocate integer memory for the second dimension of a dim[][]; */
	register int i;
	for(i = 0; i < numrows; i++) {
		data[i] = (char *) malloc(numcols * sizeof(char));
		if(NULL == data[i]){
			free(data[i]);
			printf("Memory allocation failed while allocating for dim[x][].\n");
			exit(-1);
		}
	}
	return *&data; // Success
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top