malloc a 2D array

Discussion in 'C Programming' started by mike79, Sep 11, 2003.

  1. mike79

    mike79 Guest

    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
     
    mike79, Sep 11, 2003
    #1
    1. Advertising

  2. mike79

    Tom Zych Guest

    mike79 wrote:

    > 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.

    --
    Tom Zych
    This email address will expire at some point to thwart spammers.
    Permanent address: echo '' | rot13
     
    Tom Zych, Sep 11, 2003
    #2
    1. Advertising

  3. mike79

    Kevin Easton Guest

    mike79 <> wrote:
    > 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.
     
    Kevin Easton, Sep 11, 2003
    #3
  4. mike79

    pete Guest

    mike79 wrote:
    >
    > 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 */
     
    pete, Sep 11, 2003
    #4
  5. mike79

    Tom Zych Guest

    Kevin Easton wrote:

    > 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?

    --
    Tom Zych
    This email address will expire at some point to thwart spammers.
    Permanent address: echo '' | rot13
     
    Tom Zych, Sep 11, 2003
    #5
  6. mike79

    Tom Zych Guest

    pete wrote:

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


    A C programmer who starts counting at one. How unusual... :)

    --
    Tom Zych
    This email address will expire at some point to thwart spammers.
    Permanent address: echo '' | rot13
     
    Tom Zych, Sep 11, 2003
    #6
  7. mike79

    pete Guest

    Tom Zych wrote:
    >
    > Kevin Easton wrote:


    > > 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?


    it's just unfamiliarity
     
    pete, Sep 11, 2003
    #7
  8. mike79

    vincetg2

    Joined:
    Jan 23, 2009
    Messages:
    1
    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);
    
     
    vincetg2, Jan 23, 2009
    #8
  9. mike79

    isezen

    Joined:
    May 14, 2009
    Messages:
    1
    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
    }
    
     
    isezen, May 14, 2009
    #9
  10. mike79

    WhatIThink

    Joined:
    Dec 2, 2008
    Messages:
    9
    what's the point of freeing a pointer if you already know it's null
     
    WhatIThink, Feb 25, 2011
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John
    Replies:
    13
    Views:
    723
  2. ravi
    Replies:
    0
    Views:
    469
  3. Peter
    Replies:
    34
    Views:
    2,022
    Richard Tobin
    Oct 22, 2004
  4. porting non-malloc code to malloc

    , Feb 18, 2005, in forum: C Programming
    Replies:
    3
    Views:
    492
    Walter Roberson
    Feb 19, 2005
  5. Johs32

    to malloc or not to malloc??

    Johs32, Mar 30, 2006, in forum: C Programming
    Replies:
    4
    Views:
    335
    Captain Winston
    Mar 30, 2006
Loading...

Share This Page