Reputation: 703
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
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
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
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
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