0

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

7
  • For whatever reason you have char *** it is very likely a bad idea, and also insufficient space, it should be calloc(n, sizeof(char **)); or even calloc(n, sizeof(char *)); or calloc(n, sizeof(void *)); i.e. n pointers, but not calloc(sizeof(char));. Also, don't cast calloc/malloc it could hide bugs in your program. Commented Jan 14, 2015 at 10:37
  • what do you think this *dptr[i] = GetDefinitions(); does? Commented Jan 14, 2015 at 10:40
  • 3
    Don't cast the return value of malloc() and friends in C. Commented Jan 14, 2015 at 10:41
  • what do you think is the result of int indexcount = sizeof(dptr) / sizeof(char)? Commented Jan 14, 2015 at 10:46
  • 1
    stackoverflow.com/a/25750950/775806 Commented Jan 14, 2015 at 10:58

2 Answers 2

4

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;
}
Sign up to request clarification or add additional context in comments.

9 Comments

the return just drops the program if allocation fails, is that wrong? i dont really think i can do exit(1) in a function that isnt a main()
"the return just drops the program if allocation fails, is that wrong?" It's ok, but not nice. You may call exit() any time, but in signal handlers. @Puloko
1+ for a complete answer. Still all ints shall be size_ts.
@alk I didn't notice that, since there are so many other issues, but it's a good suggestion, i will fix it.
"... be size_ts." or at least unsigned.
|
0

As already mentioned in the comment this is a very bad idea and just using double pointers is good here. But the below fixes should be done if you want to use pointers to allocate memory

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

should be

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

and

definition = calloc(n+1, sizeof(char));

should be

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

9 Comments

the point of the third degree pointers is to make dictionary dictionaryPTR>>Dynamic Array of Pointers To Another dynamic Array of pointers>>Dynamic array of pointers pointing towards addresses of arrays of words or strings which are dynamically allocated
@Puloko Don't you think just a double pointer will serve your purpose?
to be honest i have no idea
@Puloko Get rid of triple pointers ans re-design the code using double pointers and I think that is a much better idea and much easier instead of this. I don't see a need for triple pointer here
i will have to qsort the words so i think that triple pointer is still necessary,
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.