0

How can I declare an array of char* arrays? (when values will be filled later on in my program..) This is my goal:

arr[0] = {"0a","0b","0c"};
arr[0][0] = "0a";
arr[0][1] = "0b";
..
arr[1] = {"1a","1b","1c"}
  1. Is it char *arr[][] ? I feel pretty much confused.
  2. What about passing this parameter to a function?
3
  • 2
    You might get some hint if you read about the clockwise/spiral rule. Commented Apr 29, 2013 at 15:29
  • @JoachimPileborg: Worth link! Commented Apr 29, 2013 at 15:32
  • @MM. It's good for many advanced declarations, but might not be perfect for this case. For example the declaration char *v[K][L];, it's not really clear that we should skip the pointer in the first "round" and go directly to the second array. Commented Apr 29, 2013 at 15:36

5 Answers 5

2

Close, but you have to use aggregate initialization all in one shot, like so:

char arr[][2][3] = 
{
  {"0a", "0b"},
  {"1a", "1b"},
};

Note that all but the most significant (left-most) array must be explicitly sized. Or you could declare each internal string as just a pointer:

const char * arr[][2] = 
{
  {"0a", "0b"},
  {"1a", "1b"},
};

It depends on how structured your data is, and how static. An alternative is to use stl std::vector if you want to dynamically assign the contents of each array.

Sign up to request clarification or add additional context in comments.

2 Comments

i dont want to define is as a const or hard-coded array. do u mean i should define it as char * arr[][size] ? thing is im not so sure about the length of each array
@H2CO3 - thx! Popokoko - I mean if your data is known at compile time, and the structure is fixed (array counts, etc), you probably want to opt for the static representation, which is going to be simpler and faster. If your data needs to be populated once (const, after initialization), you'll need runtime support, like std::vector. Finally, if your data is going to be mutated a lot at runtime (which I doubt), you might choose a different container altogether, which expresses the complexity you need (like an std::unordered_map or something). It all just depends on program characteristics.
1

Is it char *arr[][] ?

Sound about right. But you need to provide sizes for the arrays in the declaration.

Comments

0
void fill(char *arr[10][2]) {
    arr[0][0] = strdup("k");
    arr[0][1] = strdup("ki");
    arr[1][0] = strdup("s");
    arr[1][1] = strdup("si");
}

void clean(char *arr[10][2]) {
    free(arr[0][0]);
    free(arr[0][1]);
    free(arr[1][0]);
    free(arr[1][1]);
}


int main (int argc, char *argv[]){

    char *array[10][2] = {NULL};
    fill(array);
    printf("%s   %s\n", array[0][0], array[1][1]);

    // when arr[i][j] bcome useless in your code, do not forget to free memories
    clean(array);
}

the fill and clean functions could defined as well in the following way:

void fill(char *arr[][2]) {
void clean(char *arr[][2]) {

4 Comments

Could u also note how would look a signature of a function which gets the arr as a parameter and can actually change it's content? func(char ???)
is it func(char (*arr)[][SIZE]) ? erm, im lost :(
Thank you very much, ive declared it as: char *array[10][10] = { NULL }; But im getting a warning of: (near initialization for ‘array[0]’) [-Wmissing-braces], any idea whats that?
@Popokoko provide the code I could not say the cause without see the new code
0

Any of these. Note that this is one thing almost everyone gets confused about in C.

char ** a;

Here a is a pointer to one or more pointers to one or more characters. There are a bunch of pointers somewhere in memory and each one points to a string (so to speak). a refers to the first of these pointers. (a+1) refers to the 2nd one. The blocks of characters each reside somewhere in memory but not necessarily anywhere near each other. You might do this:

for (int i = 0 ; i < 10 ; ++i) {
    a++ = malloc(100);
}

or you could do this:

char *b = malloc(1000);
for (int i = 0 ; i < 10 ; ++i) {
    a++ = b;
    b += 100;
}

And you will have filled in the array with 10 pointers to 100 characters each. (Well, really spaces for 100 characters since we didn't fill in any characters yet.)

char* a[];

Here, again, a is a bunch of pointers to the first of a bunch of characters. It's really the same as char ** a but makes more sense if you are going to reuse them all.

for (int i = 0 ; i < 10 ; ++i) {
    a[i] = malloc(100);
}

which will do the same thing as above but leaves it easier to get back to any given block of characters. For example, we could do strcpy(a[4], "Bob was here");

char a[][];

This is a little different in that it is a pointer to a bunch of characters that can be broken up into blocks of the same length. You would typically give sizes in this case unless its too big to allocate on the stack. char a[10][100] would allocate 1000 character spots in memory with them divided into 10 groups of 100 each.

Notice that your example {"0a","0b","0c"}; is a way to allocate three blocks of memory. Each is three bytes long and is pre-populated with the characters there (and a closing \0 character.

5 Comments

More practically - Could u tell the differences please?
Yeah. It sort of depends on what he means.
I don't understand how any of these solutions gives what i ment. char *a[] is an array of strings, and char a[][] is a 2d matrix of single chars isnt it?
They are all just ways of referencing the blocks of memory occupied by characters. The [][] way implies all the memory for the characters has to be one big block. The others can have the memory that way or not.
Your explanation is well explained but that keeps me confused and i ain't sure which of these fits as a solution to my problem. so lets say i have 10 rows and i want to put different arrays inside each of the rows, how would u declare the array?
0
int main (int argc, char *argv[]){

    char arr[10][2][3] = {0};

    memcpy(&arr[0][0], "k", sizeof(arr[0][0]));
    memcpy(&arr[0][1], "ki", sizeof(arr[0][0]));
    memcpy(&arr[1][0], "s", sizeof(arr[0][0]));
    memcpy(&arr[1][1], "si", sizeof(arr[0][0]));

    printf("%s   %s\n", arr[0][0], arr[1][1]);

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.