Search code examples
cpointersdynamic-allocation

pointer to dynamic array of pointers to dynamic array of pointer that points to strings


i have a problem with the initialization of the values inside the first dynamic array of pointers

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char*** GetIndexes()
{
int n = 0;
char ***index;
printf("please insert the number of words you want to add to dictionary\n");
scanf("%d", &n);
index = (char***)calloc(n, sizeof(char));
if (index == NULL)
{
    printf("allocation Failed");
    return;
}
return index;
}
char** GetDefinitions()
{
int n = 0;
char **definition;
printf("please insert the number of defintions you want to add to the word\n");
scanf("%d", &n);
definition = (char**)calloc(n+1, sizeof(char));
if (definition == NULL)
{
    printf("allocation failed");
    return;
}
return definition;
}
int main()
{
char *** dptr = GetIndexes();
if (dptr == NULL)
{
    printf("memory Allocation failed");
}
int indexcount = sizeof(dptr) / sizeof(char),i;
for (i = 0; i < indexcount; i++)
{
    printf("word number %d\n", i + 1);
    *dptr[i] = GetDefinitions();
}
printf("%p",dptr);

}

i tried running the debugger in VS2013 and after i enter the number of defintions i want it crashed with this message:

Unhandled exception at 0x01103FB0 in ConsoleApplication1.exe: 0xC0000005: Access violation writing location 0x00000000.

i missed an allocation of something but i cant quite figure out what i missed,

thanks in advance


Solution

  • Your program is very broken

    1. You allocate n char ***s but only request space for n chars and also do it for char **, to prevent this kind of mistake you may use the sizeof operator this way

      char ***index;
      index = calloc(n, sizeof(*index));
      

      and

      char **definition;
      definition = calloc(n, sizeof(*definition));
      

      and as you see casting calloc makes it harder and it's not necessary.

    2. You have a return statement that doesn't return anything an GetIndexes() as well as one in GetDefinitions.

      They should return NULL if you want to handle failure in the caller function

      return NULL;
      
    3. You erroneously use the sizeof operator to determine the number of char *** pointer allocated in

      int indexcount = sizeof(dptr) / sizeof(char)
      

      this will be either 4 or 8 depending on the architecture i.e. the size of a pointer divided by 1 sizeof(char) == 1 always.

      You can't compute that value, you simply have to keep track of it. The size

    4. You dereference the triple pointer twice and try to assign a double pointer to it

      *dptr[i] = GetDefinitions();
      

      here the operator precedence is also an issue, but regardless of that, this is wrong, may be what you meant was

      dptr[i] = GetDefinitions();
      
    5. This is not going to make your program crash, but it's certainly important to free all malloced pointers before exiting the program.

    Here is a suggestion for your code to work, ignore it's purpose since it's not clear what you are trying to do

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char ***GetIndexes(unsigned int *count)
    {
        char ***index;
    
        printf("please insert the number of words you want to add to dictionary > ");
        scanf("%u", count);
    
        index = calloc(*count, sizeof(*index));
        if (index == NULL)
        {
            printf("allocation Failed");
            return NULL;
        }
    
        return index;
    }
    
    char **GetDefinitions(unsigned int *count)
    {
        char **definition;
    
        printf("please insert the number of defintions you want to add to the word > ");
        scanf("%u", count);
    
        definition = calloc(*count + 1, sizeof(*definition));
        if (definition == NULL)
        {
            printf("allocation failed");
            return NULL;
        }
        return definition;
    }
    
    int main()
    {
        unsigned int indexCount, i;
        char      ***dptr = GetIndexes(&indexCount);
    
        if (dptr == NULL)
        {
            printf("memory Allocation failed");
        }
    
        for (i = 0; i < indexCount; i++)
        {
            unsigned int definitionsCount;
    
            printf("Word number %u\n", i + 1);
            dptr[i] = GetDefinitions(&definitionsCount);
            if (dptr[i] != NULL)
            {
                /* use dptr[i] here or maybe somewhere else, but when you finish */
                free(dptr[i]);
            }
        }
        printf("%p", dptr);
        /* now if you are done using dptr */
        free(dptr);
    
        return 0;
    }