Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializing 2D char array in C

Similar to this question: 2d array, using calloc in C

I need help initializing a 2D char array that will all be initialized to some value (in this case '0'). I have tried many different methods and I am pulling my hair out. Please let me know what I am doing wrong. This code doesn't work. Thanks!

char** init_array() {
        char newarray[5][10];
        int i, j;
        for (i = 0; i < 5; i++) {
                for (j = 0; j < 10; j++) {
                        newarray[i][j] = '0';
                }
        }
        return newarray;
}
char **array = init_array();

The errors I get from gcc when I try to compile:

test.c: In function ‘init_array’:
test.c:12:2: warning: return from incompatible pointer type [enabled by default]
  return newarray;
  ^
test.c:12:2: warning: function returns address of local variable [-Wreturn-local-addr]
test.c: At top level:
test.c:14:1: error: initializer element is not constant
 char **array = init_array();

Should it be like this?

char newarray[5][10];
char** init_array() {
        int i, j;
        for (i = 0; i < 5; i++) {
                for (j = 0; j < 10; j++) {
                        newarray[i][j] = '0';
                }
        }
        return newarray;
}
char **array = init_array();
like image 345
mallux Avatar asked Nov 15 '14 01:11

mallux


3 Answers

I think pictures help. Here is char newarray[5][10]. It is a single memory block consisting of an array of 10 characters, and an array of five of those. You could just clear it with a single memset call.

enter image description here

Here is char **array. It says array is a pointer. What is it a pointer to? a pointer to a character.

enter image description here

Keep in mind pointer arithmetic. If array is a pointer that happens to point to a pointer, then (*array) equals array[0], and that is the pointer that array points to.

What is array[1]? It is the second pointer in the array that array points to.

What is array[0][0]? It is the first character pointed at by the first pointer that array points to.

What is array[i][j]? It is the jth character of the ith pointer that array points to.

So how are newarray and array related?
Simple. newarray[i][j] is the jth character of the ith subarray of newarray.

So in that sense, it's just like array, but without all the pointers underneath.

What's the difference? Well, the disadvantage of array is you have to build it up, piece by piece. OTOH, the advantage is you can make it as big as you want when you build it up. It doesn't have to live within a fixed size known in advance.

Clear as mud?

like image 57
Mike Dunlavey Avatar answered Nov 07 '22 15:11

Mike Dunlavey


Per our discussion in the comments, here is a quick example of zeroing array values at the time of declaration. Note, the values are #defined as constants:

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

#define MAXSTR 10
#define MAXLEN 1024

int main () {

    char myarray[MAXSTR][MAXLEN] = {{0}};  /* declare a static array of MAXSTR x MAXLEN */

    /* copy various strings to statically declared storage */
    strncpy (myarray[0],"  This is the first string", strlen("  This is the first string")+1);
    strncpy (myarray[1],"  This is the second string", strlen("  This is the second string")+1);
    strncpy (myarray[2],"  This is the third string", strlen("  This is the third string")+1);
    strncpy (myarray[3],"  This is the fourth string", strlen("  This is the fourth string")+1);
    strncpy (myarray[4],"  This is the fifth string", strlen("  This is the fifth string")+1);

    int i = 0;

    /* print the values */
    while (*myarray[i])
        printf ("  %s\n", myarray[i++]);

    return 0;
}

output:

$ ./myar
    This is the first string
    This is the second string
    This is the third string
    This is the fourth string
    This is the fifth string

build:

gcc -Wall -Wextra -o myar myarray.c
like image 40
David C. Rankin Avatar answered Nov 07 '22 15:11

David C. Rankin


To avoid using a global (like the second sample code pasted above) and to avoid using malloc, you can define the array outside your function and pass it in, like this. You don't need to return anything because the array data itself is being modified. Notice that it's necessary to define the array's secondary dimension in the function signature:

void init_array(char ary[][10]) {
    int i, j;
    for (i = 0; i < 5; i++) {
        for (j = 0; j < 10; j++) {
                ary[i][j] = '0';
        }
    }
}

int main(void)
{
    char newarray[5][10];
    init_array(newarray);
    printf("%c", newarray[1][1]); /* Testing the output */
    return 0;
}

That returns '0'.

http://codepad.org/JbykYcyF

like image 1
twasbrillig Avatar answered Nov 07 '22 16:11

twasbrillig