tags:

views:

73

answers:

5

Suppose I have a block of memory as such:

void *block = malloc(sizeof(void *) + size);

How do I set a pointer to the beginning of the block while still being able to access the rest of the reserved space? For this reason, I do not want to simply assign 'block' to another pointer or NULL.

+2  A: 
memset(block, 0, 2);

memset can be found in string.h

KillianDS
+4  A: 

How do I set the first two bytes of the block as NULL or have it point somewhere?

This doesn't make any sense unless you're running on a 16-bit machine.

Based on the way that you're calling malloc(), you're planning to have the first N bytes be a pointer to something else (where N may be 2, 4, or 8 depending on whether you're running on a 16-, 32-, or 64-bit architecture). Is this what you really want to do?

If it is, then you can create use a pointer-to-a-pointer approach (recognizing that you can't actually use a void* to change anything, but I don't want to confuse matters by introducing a real type):

void** ptr = block;

However, it would be far more elegant to define your block with a struct (this may contain syntax errors; I haven't run it through a compiler):

typedef struct {
    void* ptr; /* replace void* with whatever your pointer type really is */
    char[1] data; } MY_STRUCT;

MY_STRUCT* block = malloc(sizeof(MY_STRUCT) + additional);
block->ptr = /* something */
Anon
why do you care how many bytes the pointer points to? That makes no sense at all.
KillianDS
@KillianDS - the OP showed a malloc that was based on the size of a pointer. As I and other people have responded, 2 bytes is not large enough for a pointer on a modern machine.
Anon
Sorry, I got confused :).
KillianDS
A: 
void *block = malloc(sizeof(void *) + size); // allocate block
void *ptr = NULL; // some pointer
memcpy(block, &ptr, sizeof(void *)); // copy pointer to start of block
Paul R
+1  A: 

Putting the first two bytes of the allocated memory block to 0 is easy. There is many ways to do it, for example:

((char*)block)[0] = 0;
((char*)block)[1] = 0;

Now, the way the question is asked show some misunderstanding.

You can put anything in the first two bytes of your allocated block, it doesn't change anything for accessing the following bytes. The only difference is that C string manipulation operator use as a convention that strings end with a 0 byte. Then if you do things like strcpy((char*)block, target) it will stop copying immediately if the first byte is a zero. But you can still do strcpy((char*)block+2, target).

Now if you want to store a pointer a the beginning of the block (and usually it's not 2 bytes). You can do the same thing as above but using void* instead of char.

((void**)block)[0] = your_pointer;

You access the rest of the block as you like, just get it's address and go on. You could do it for example with.

void * pointer_to_rest = &((void**)block)[1];

PS: I do not recommand such pointer games. They are very error prone. Your best move would probably be to follow the struct method proposed by @Anon.

kriss
A: 

I have a guess at what you're trying to ask, but your wording is so confusing that I could be totally wrong. I am assuming that you want a pointer that points to the "first 2 bytes" of the block you allocated, and then another pointer that points to the rest of the block.

Pointers carry no information about the size of the memory block that they point to, so you can do this:

void *block = malloc(sizeof(void *) + size);
void *first_two_bytes = block;
void *rest_of_block = ((char*)block)+2;

Now, first_two_bytes points to the beginning of the block that you allocated, and you should just treat it as if it pointed to a memory area 2 bytes long.

And rest_of_block points to the portion of the block starting 3 bytes in, and you should treat it as if it pointed to a memory area 2 bytes smaller than what you allocated.

Note, however, that this is still only a single allocation, and you should only free the block pointer. If you free all three pointers, you will corrupt the heap, since you will be calling free more than once on the same block.

Tyler McHenry