0

My code compiles just fine, but I'm still a little rough on the pointer and array concepts. I would appreciate your help very much.

void initialize(int individual_count, int family_count, char ***indiIDs,
                char ***names, char ***spousesIDs, char ***childIDs)
//so here I declared two int variables and four triple pointers,
// which are pointer to a pointer to a pointer to an integer, correct?
{
    int i;

    //malloc allocates memory space and returns the address of the
    // first byte to the pointer *indiIDs,right?

    (*indiIDs) = (char**)malloc(sizeof(char*) * individual_count);
    (*names) = (char**)malloc(sizeof(char*) * individual_count);
    for(i = 0; i <individual_count; i++)
    {
        (*indiIDs)[i] = (char*)malloc(sizeof(char) * 20);
        (*names)[i] = NULL;
    }

    //*indiIDs[i] is an array of pointers, correct? so what exactly
    //  is the difference between mallocing and returning to *indiIDs
    //  and then to *indiIDs[i] as seen here?

    (*spousesIDs) = (char**)malloc(sizeof(char*) * family_count);
    (*childIDs) = (char**)malloc(sizeof(char*) * family_count);
    for(i = 0; i < family_count; i++)
    {
        (*spousesIDs)[i] = (char*)malloc(sizeof(char) * 40);

        //since spousesIDs[][] is a 2D array, would *spousesIDs[][]
        // indicate a triple array then?

        (*spousesIDs)[i][0] = '\0';
        (*childIDs)[i] = NULL;
    }
}
alk
  • 69,737
  • 10
  • 105
  • 255
Bonnie
  • 461
  • 3
  • 11
  • 14
  • 9
    What is your question? – n. m. could be an AI Feb 27 '13 at 06:27
  • 2
    Read a good C programming book. You usually should assign the result of `malloc` to some direct pointer (e.g. to `indiIDs` not `(*indiIDs)` in your case). Compile with all warnings & debug info (e.g. `gcc -Wall -g` on Linux). Learn to use the debugger (`gdb` on Linux). Also use a memory leakage detector (e.g. `valgrind` on Linux). – Basile Starynkevitch Feb 27 '13 at 06:28
  • 1
    You don't need to cast the return value of `malloc` in a C program. And `sizeof(char)` is `1`. If you take that stuff out, your code will look a lot less messy, and maybe that will help you to understand it. – Carl Norum Feb 27 '13 at 06:29
  • In fact, "don't need to" isn't strong enough. You _shouldn't_ cast `malloc` return value _at all_ in C - it can hide certain subtle errors. – paxdiablo Feb 27 '13 at 06:31
  • The professor taught us to cast it though. – Bonnie Feb 27 '13 at 06:33
  • 3
    This is a nice question with answer explaining why result from `malloc` should not be cast: http://stackoverflow.com/questions/1565496/specifically-whats-dangerous-about-casting-the-result-of-malloc – nhahtdh Feb 27 '13 at 06:37
  • 4
    It would probably be easier to pass a structure into the function than a set of triple pointers. I would regard triple pointers as a danger sign; a sign that there is a mistake in the design, somehow. As for casting the result of `malloc()`, there are worse crimes in C programming (probably including triple pointers). – Jonathan Leffler Feb 27 '13 at 06:44
  • 4
    You're not as rough as you think, other than doing more work than needed if you use the built-in zero-initializing vector allocator `calloc()` to allocate your arrays. [See example here](http://ideone.com/CV1rvf). That being said, use a structure as Jonathan suggested. It makes things significantly better organized. – WhozCraig Feb 27 '13 at 06:45
  • Would this be better on codereview? – luser droog Feb 27 '13 at 09:54

1 Answers1

0

Your example doesn't show a 3D array, but a 2D array:

void init2D(char * ** x, int w, int h)
{
    (*x) = (char**)malloc(sizeof(char*) * w);

    for (i=0; i<w; i++) (*x)[i] = (char*)malloc(sizeof(char) * h);
}

The reason it has an additional * as a function parameter, is because C doesn't have pass-by-refence like C++

It's used this way:

void main ()
{

    char ** lines = 0;

    init2D (&lines, 4, 256); // char[256] x 4

}
Khaled.K
  • 5,828
  • 1
  • 33
  • 51