I'm a bit new to C and I'm having trouble understanding how memory works, especially in-built functions like memcpy
.
Here's a struct
I'm using
struct data_t {
int datasize;
void *data;
};
And here's an auxiliary function that I'm using it with:
struct data_t *data_create(int size)
{
struct data_t *dt=malloc(sizeof(struct data_t)+size);
dt->datasize=size;
dt->data="1234567890a";
return dt;
}
Now in the main
function I have no problem doing this:
struct data_t *data = data_create(1024);
data->data="123456a";//just an example
But this throws a Seg Fault:
memcpy(data->data,"123456a",strlen("1234567890a")+1);
My question is why? And how do I avoid it? Please bear in mind I'm new to C so how C deals with memory is a bit new to me
Thank you.
Edit: It works! Thank you very much. Completly missed the data pointer. Now everything is working fine according to valgrind.
In C, the library function malloc is used to allocate a block of memory on the heap. The program accesses this block of memory via a pointer that malloc returns. When the memory is no longer needed, the pointer is passed to free which deallocates the memory so that it can be used for other purposes.
In the C Programming Language, the memcpy function copies n characters from the object pointed to by s2 into the object pointed to by s1. It returns a pointer to the destination. The memcpy function may not work if the objects overlap.
The function memcpy() is used to copy a memory block from one location to another.
Dynamic memory allocation is mostly a non-issue in Python. Everything is an object, and the reference counting system and garbage collector automatically return memory to the system when it is no longer being used.
memcpy(data->data,"123456a",strlen("1234567890a")+1);
fails because data->data
a void *
type points to some garbage/invalid address which is not allocated. data
has the address of the string literal which is stored in the readonly section (like in the .rodata
of the executable and loaded in the memory, which is not writable. Also, if you did not assign such a string address to the pointer variable, then it would hold some invalid/garbage address value which is not allocated or initialized with some valid permitted location. So first allocate the buffer.
data->data = malloc (sizeof (char) * size);
The malloc
will return the first location address of a block of address of atleast size * sizeof (char)
bytes. Now you can copy size
bytes to this memory location pointed by data->data
.
Remember to free the allocated memory block when you have finished working with that memory bock with the free (addr)
call.
I see you have tried to allocate data
buffer with a very strange manner (?):
struct data_t *dt=malloc(sizeof(struct data_t)+size);
for which the extra allocated size
bytes along with the struct data_t
. But what ever be the case, data
component still points to some place which cannot be changed.
Please use:
struct data_t *dt = malloc(sizeof(struct data_t));
dt->data = malloc (sizeof (char) * size);
memcpy (data->data, "whatever", sizeof ("whatever")+1);
return dt;
to free first do:
free (dt->data);
then
free (dt);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With