0

I'm trying to create array of void pointers inside my struct to see if that is possible. I want to be in charge of the memory allocation and to be able to update the value for each array by index. The value data type is not specified as i want to accept any data type.

This is what i did:

typedef struct {
    void ** value;
} bucket;


void updateValue(bucket * data, index, void * value)
{
    if(data->value[index] == NULL)
    {
       data->value[index] = (void*)calloc(1, sizeof(void*));
    }

    data->value[index] = value;
}


bucket * clients = calloc(1, sizeof(bucket));

clients->value = (void **)calloc(3,  sizeof(void*));

clients->value[0] = NULL;
clients->value[1] = NULL;
clients->value[2] = NULL;


updateValue(clients, 0, (void*) (int)124);

printf("Client0 Value: value: %d\n",     (int)&clients->value[0]);

The code compile, but does not output 124 as value. I don't know what is wrong. Can someone please help me to correct it and explain what wrong so i can learn?

Jorhn Madsen
  • 129
  • 8

1 Answers1

1

You stored (void*) (int)124 to clients->value[0].

This means that the value is stored to the element, not as the address of the element.

Because of that , the printing statement should be

printf("Client0 Value: value: %d\n",     (int)clients->value[0]);

without the extra &.

Also note that the part

    if(data->value[index] == NULL)
    {
       data->value[index] = (void*)calloc(1, sizeof(void*));
    }

should be removed to avoid memory leaks caused by allocating unused buffer and soon overwriting its address.


Maybe you want this (allocating buffer and copy the data there):

#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* for using memcpy() */

typedef struct {
    void ** value;
} bucket;


void updateValue(bucket * data, index, void * value, size_t valueSize)
{
    data->value[index] = realloc(data->value[index], valueSize);
    memcpy(data->value[index], value, valueSize);
}


bucket * clients = calloc(1, sizeof(bucket));

clients->value = (void **)calloc(3,  sizeof(void*));

clients->value[0] = NULL;
clients->value[1] = NULL;
clients->value[2] = NULL;


int value = 124;
updateValue(clients, 0, &value, sizeof(value));

printf("Client0 Value: value: %d\n",     *(int*)clients->value[0]);
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
  • Thank you for your response. data->value[index] = (void*)calloc(1, sizeof(void*)); is needed so i can later free it. But it crash on free(clients->value[0]); and not free(&clients->value[0]);, why? – Jorhn Madsen May 14 '20 at 14:13
  • You invoked *undefined behavior* by out-of-range access (`clients->value` has 3 elements and it is less than 5) and your result is given by chance. – MikeCAT May 14 '20 at 14:15
  • Sorry, i know that it was out-of-range access - i wrote it fast. Meant free(clients->value[0]); crash, but not free(&clients->value[0]); – Jorhn Madsen May 14 '20 at 14:16
  • Because `clients->value[0]` is not a pointer allocated via `malloc()` family after assigning `(void*) (int)124` while `&clients->value[0]` is because it is `clients->value`. – MikeCAT May 14 '20 at 14:19
  • Last question, i changed (void*) (int)124 to int randomNumber = 129; updateValue(clients, 0,&randomNumber);, but calling free(clients->value[0]); crash, why? – Jorhn Madsen May 14 '20 at 14:31
  • Because `&randomNumber` is not a pointer allocated via `malloc()` family. – MikeCAT May 14 '20 at 14:31
  • But i'm doing it in this line: data->value[index] = (void*)calloc(1, sizeof(void*)); – Jorhn Madsen May 14 '20 at 14:33
  • But the address is overwritten. – MikeCAT May 14 '20 at 14:34
  • You deserve the accept ! thank you very, very much! – Jorhn Madsen May 14 '20 at 14:45
  • Just one small question. The address is overwritten, because clients->value = (void **)calloc(3, sizeof(void*)); is written and then inside the function updateValue we wrote data->value[index] = (void*)calloc(1, sizeof(void*)); ? i thought that first we allocate for the array structure itself memory and then the each index cell inside it. – Jorhn Madsen May 14 '20 at 15:01
  • No, it is not the reason why the address is overwritten. The overwritting is done at `data->value[index] = value;`. – MikeCAT May 14 '20 at 17:48