How could I recover the value of a memset?
In the following code, the program is supposed to allocate a certain amount of space requested by the user and store the size the user requested ahead of the pointer returned to the user:
void* my_malloc(size_t sz)
void* block = malloc(sz + sizeof(size_t));
void* retval = &block + sizeof(size_t);
memset(block, sz, sizeof(size_t));
return retval;
In another function, the user can pass in the pointer of their data and I want to recover the size that I stored ahead of their memory.
void my_free(void *ptr) {
void* block = ptr - sizeof(size_t);
size_t *sz;
memset(sz, block, sizeof(size_t));//This is the line in question.
free(block);
Is there any kind of memread function I can use the reset the value of sz? This current method is giving me errors
You really need to read the documentation of memset
. It sets a block of memory to have all bytes the same. The effect of memset(block, sz, sizeof(size_t))
is to set the first 8
(or whatever the size of size_t
is) bytes of block
to all be (unsigned char)sz
.
To copy some bytes the correct function is memcpy
, so that line should be:
memcpy(block, &sz, sizeof sz);
In the free
function you want:
size_t sz;
memcpy(&sz, block, sizeof sz);
Also, you do incorrect pointer arithmetic in two places:
void *retval = &block + sizeof(size_t); // moves sizeof(size_t) * sizeof(void *) bytes
void *block = ptr - sizeof(size_t); // illegal
The definition of pointer arithmetic is to move by that number of elements of the type being pointed to. You seem to be assuming it is the number of bytes. What you really want, respectively, is:
void *retval = (char *)block + sizeof(size_t);
void *block = (char *)ptr - sizeof(size_t);
The cast is because pointer arithmetic is not defined for void *
. Since sizeof(char) == 1
then doing pointer arithmetic on a char *
moves you by that number of bytes.
If you understand the pointer arithmetic correctly then you will realize that another way to write those statements is:
void *retval = (size_t *)block + 1;
void *block = (size_t *)ptr - 1;
Finally your malloc replacement will fail for any type that has a greater alignment requirement than size_t
(although it's likely that your system doesn't have any such types).