Memcpy with a void pointer

15,905

Solution 1

Your function parameter data needs to point to somewhere that there is memory available. You could do something like this:

int main()
{
  char myString[256];
  saveData((void*)myString);
}

If you prefer to use malloc and free, then your code would be more like this:

int main()
{
  char* myString = (char*)malloc(256);
  saveData((void*)myString);
  free(myString);
}

..the trouble with both of these is that you don't know how long the string needs to be. It would be far safer/easier to use std::string.

std::string myString;  // an empty string
myString += "some data"; // append a string

Solution 2

Note that the size of the source is not given by sizeof but by strlen. Assuming the caller does not want to allocate memory, you need to malloc storage and have the void* store a handle to that. Given the save function calls malloc, I'd set up a corresponding release function.

bool saveData(void** retSave, const char* input)
{
    bool success = false;
    size_t storageSize = strlen(input) + 1;
    void* store = malloc(storageSize);
    if (store)
    {
        memcpy(store, input, storageSize);
        success = true;
    }
    return success;
}



void releaseSavedData(void* savedData)
{
    free(savedData);
}

int main()
{
    void* saveHandle = 0;
    bool ok = saveData(&saveHandle, "some data");
    if (ok)
    {
        releaseSavedData(saveHandle);
    }
    return 0;
}

Solution 3

data needs to point to somewhere you have access to write. The null pointer area you don't have access to (unless you're running DOS or something).

Use malloc to allocate a chunk of memory to copy from inputData to.

Solution 4

If you don't know the size of the data ahead of time, the only way to get this to work is to malloc some arbitrarily large buffer and make sure you NEVER copy more than that # of bytes into the void*. Not the best design, but it will work.

Also, don't forget to allocate an extra byte for the NULL char on the end of the string, and don't forget to actually put the null on the end of the memory buffer. In the example above, your string in data won't have a NULL on the end.

Share:
15,905
Ann
Author by

Ann

Updated on June 14, 2022

Comments

  • Ann
    Ann about 2 years

    I am having trouble with the memcpy function. I need a function that stores data into a void pointer. Here is a simple example of it:

    void saveData(void* data)
    {
      char inputData[] = "some data";
      memcpy((char*)data, inputData, sizeof(inputData));
    }
    

    However I get segmentation errors when I do this, even though it compiles just fine. My function argument has to be a void pointer because I may have different data formats to input and I may not know the size of the data ahead of time. Could somebody tell me what I am doing wrong?

    Please and thank you.

    ***UPDATE: Thanks all for the helpful responses. As most of you pointed out, I did not initialize void* data. That fixed it. Now my question is: when I do dynamic allocation for the void* data (or even char* data), I give it a size, but when I do memcpy, it allows me to write an ever bigger string than I first assigned space for. I also tried just doing char* data, and the same thing happens. This is my sample code:

    char inputData[] = "123456789";
    void* data1 = malloc(5*sizeof(char));
    char* data2 = (char*)malloc(5*sizeof(char));
    
    memcpy(data1,inputData,sizeof(inputData));
    memcpy(data2,inputData,sizeof(inputData));
    

    When I print out the results, the entire string of inputData get copied even though I only allocated enough space for 5 chars. Shouldn't that give me an error?

  • tom
    tom about 11 years
    The question is tagged with C so I'm assuming std::string is out of scope. But the rest of this answer looks great.