Home > Enterprise >  Passing a struct to void* param then copying it to a void*, reconstructing gives garbage value
Passing a struct to void* param then copying it to a void*, reconstructing gives garbage value

Time:04-04

I am really confused with passing my struct to void pointers, I'm not sure which one can be assigned directly and which one should be memcpyed, I've tried a lot of combinations but it does not seem to work. Any help would be very appreciated!

This is my C code

struct SomeStruct {
  int a;
  char name[10];
};

void *randoms[10];

void transferFunction(void* data, int index) {
    // This function copies data to randoms[index]
    // I would like to have the whole struct's data in randoms[index]
    memcpy(&randoms[index], data, sizeof(struct SomeStruct));
}        

struct SomeStruct *ss = malloc(sizeof(struct SomeStruct)); 
ss->a = 1;
strcpy(ss->name, "abc");
transferFunction(ss, 0);

My goal is to have the randoms[index] having the struct's data as another function is going to read from it, as shown below, but I am unable to retrieve the struct data correctly, it gives me some garbage value

void readFunction() {
     struct *SomeStruct ss = malloc(sizeof(struct SomeStruct)); 
     memcpy(ss, &randoms[index], sizeof(struct SomeStruct));
     printf(ss->name);
}

Does anyone knows how to solve this problem? Thank you very much!!!

CodePudding user response:

You can not "copy in to a void".

A void * can contain a memory address, but does not contain any information about the size of the data at that address.

Also, it can not contain any data, only an address!

In this line:

void *randoms[10];

You create an array that can hold 10 addresses.

You never initialize this array, so it will start out all zeroes (this only works for global variables in C).

You can put the address of your structure in to the array, like so:

random[0] = (void*)ss;

However, this does not transfer any data, so if you free the original structure (ss) your data is gone, and the address in random[0] is illegal.

If you want to transfer data you need to create array of struct SomeStruct or you need to allocate another SomeStruct, store its address in random[0] then memcpy to that address.

void transferFunction(void* data, int size, int index)
{
    randoms[index] = malloc(size);
    if (randoms[index] != NULL) {
        memcpy(randoms[index], data, size);
    }
}

CodePudding user response:

Your code has errors:

  • Add a ; at the end of your struct declaration.
  • struct *SomeStruct ss = ... should be struct SomeStruct *ss =.
  • ss->name = "abc";: you are assigning an expression (const char*) to an array type. You should use strncpy() like this: strncpy(ss->name, "abc", sizeof("abc"));
  • transferFunction() accepts two parameters, but you are calling it with one only. It should be something like: transferFunction(ss, 1).
  • You are not cheking the return value of malloc() (which may fail).
  • You are not freeing ss allocated with malloc(). You should call free() on ss.

Your code will look like this:

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

struct SomeStruct {
    int a;
    char name[10];
};

void *randoms[10];

void transferFunction(void* data, int index)
{
    // This function copies data to an array of void*
    memcpy(&randoms[index], data, sizeof(struct SomeStruct));
}        

int main(void)
{
    struct SomeStruct *ss = malloc(sizeof(struct SomeStruct));
    if (!ss) {
        printf("malloc() failed.\n");
        return EXIT_FAILURE;
    }
    
    ss->a = 1;
    strcpy(ss->name, "abc");
    transferFunction(ss, 1);
    free(ss);
}

And it runs without errors.

  •  Tags:  
  • c
  • Related