1

I need to create an array of pointers that will each point to an array of strings. The base, is a size 2 array of strings (the length of the strings is unknown at start). For example an array of 2 strings (first-name and last-name):

char *name[2];

Now I need to create an array of an unknown size (entered by the user) that will point to the type that I just created. My idea was to create it this way:

char **people=name;

And then ask the user how many names he would like to enter and allocate enough space to hold all the names.

people=(char**)malloc(sizeof(char*)*num); //num is the number received by the user.

This is where things got too complicated to me and I can't figure out how to I call each individual name to put a string in it. I built a loop that will receive all the names but I have no idea how to store them properly.

for(i=0;i<num;i++){
    printf("Please enter the #%d first and last name:\n",i+1);
    //Receives the first name.
    scanf("%s",&bufferFirstName);
    getchar();
    //Receives the last name (can also include spaces).
    gets(bufferLastName);
    people[i][0]=(char*)malloc(strlen(bufferFirstName)+1);
    people[i][1]=(char*)malloc(strlen(bufferLastName)+1);
    //^^Needless to say that it won't even compile :(
} 

Can anyone please tell me how to properly use this kind of an array of points? Thanks.

3
  • 1
    people[i][0]=(char*)malloc(strlen(bufferFirstName)+1); is wrong. if people is a char** then people[0] is a char* and people[i][0] is a char. Not a pointer. Also: don't cast malloc()s return value. It is not needed and possibly dangerous, since it can hide errors. Commented Dec 11, 2013 at 20:51
  • So people should be a *** type instead of ** (char ***people)? Also, is there a way of defining people in one line without the use of *name[2]? Commented Dec 11, 2013 at 20:54
  • From the question it is not clear what is your intention. I just point out the obvious error(s). And in most cases: when you start thinking of *** you should consider using structs (like in @msider(s) answer) Commented Dec 11, 2013 at 21:01

2 Answers 2

3

from cdecl:

declare foo as array of pointer to array 2 of pointer to char

char *(*foo[])[2];

So, foo[0] is a pointer to array 2 of char *

That is the array, but for your use, you want:

declare foo as pointer to array 2 of pointer to char;

char *(*foo)[2];

Now you can do:

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

int main() {
    char *(*foo)[2];

    printf("How many people?\n");
    int n; scanf("%d", &n);

    foo = malloc(sizeof *foo * n);

    for (int i = 0; i < n; i++) {
        char bufFirstName[1024];
        char bufLastName[1024];

        printf("Please insert the #%d first and last name:\n", i+1);

        scanf("%s %s", bufFirstName, bufLastName); 

        char *firstName = malloc(strlen(bufFirstName) + 1);
        char *lastName = malloc(strlen(bufLastName) + 1);

        strcpy(firstName, bufFirstName);
        strcpy(lastName, bufLastName);

        foo[i][0] = firstName;
        foo[i][1] = lastName;
    }

    for (int i = 0; i < n; i++) {
        printf("Name: %s LastName: %s\n", foo[i][0], foo[i][1]);
    }

    return 0;
}

Compile with -std=c99

Note that using scanf, strcpy, strlen like that is unsafe because there can be a buffer overflow.

Also, remember to free your malloc's!

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

4 Comments

When I'm trying to use it, it shows an error "Error: Incomplete type is not allowed".
It was when I tried using char *(*foo[])[2]; (before you edited the post).
Sorry, the first thing is the actual answer to your question (that's what you asked :P). The rest of the post is what I think that you wanted.
Thanks a lot. I have finally managed to get something going after hours of frustration XD.
0

Not that your approach is wrong, but have you considered instead using a struct that includes first and last name, and then malloc'ing based on the number of names the user will enter:

typedef struct {
    char* first;
    char* last;
} person;

person* people = malloc(num * sizeof(*person));

This just simplifies pointer interaction. While the way you are doing it is a good exercise in understanding pointers better, it may not be the easiest way to understand.

If you are unable to use structs, you should instead be doing:

char** people;  
people = malloc(2*num*sizeof(char*));  

for (int i = 0; i < 2*num; i++) 
    people[i] = malloc(MAX_NAME_SIZE*sizeof(char));

Now you would need to reference the i th person via:

first name: people[i*2 + 0] 
last name: people[i*2 + 1]

5 Comments

I am not allowed to use ***.
BTW: the downvote was mine, unintentionally, must have been a clicko. The silly CMS does not allow me to correct it. yet.
No worries, I thought it must have been a mistake by someone as it was downvoted almost instantly as I posted it.
The line people[i][0] = malloc(MAX_NAME_SIZE*sizeof(char)); shows an error "Error: a value type "char*" cannot be assigned to an entity of type "char"".
Woops, yeah I had a mistake there, but it's fixed now. @Marco has a good solution.

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.