Ann
Ann

Reputation: 703

Memcpy with a void pointer

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?

Upvotes: 2

Views: 17957

Answers (4)

axon
axon

Reputation: 1200

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

Upvotes: 4

Keith
Keith

Reputation: 6834

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;
}

Upvotes: 2

edtheprogrammerguy
edtheprogrammerguy

Reputation: 6049

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.

Upvotes: 1

PaulProgrammer
PaulProgrammer

Reputation: 17690

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.

Upvotes: 1

Related Questions