2

If I create a void pointer, and malloc a section of memory to that void pointer, how can I print out the individual bytes that I just allocated?

For example:

void * p;
p = malloc(24);
printf("0x%x\n", (int *)p);

I would like the above to print the 24 bytes that I just allocated.

Cristik
  • 30,989
  • 25
  • 91
  • 127
kubiej21
  • 700
  • 4
  • 14
  • 29

6 Answers6

5
size_t size = 24;
void *p = malloc(size);

for (int i = 0; i < size; i++) {
  printf("%02x", ((unsigned char *) p) [i]);
}

Of course it invokes undefined behavior (the value of an object allocated by malloc has an indeterminate value).

ouah
  • 142,963
  • 15
  • 272
  • 331
  • +1, but perhaps you could leave out that comment on undefined behavior. It's already implicit in the question. The OP wants to know what the memory looks like right after `malloc`. – s.bandara Feb 01 '13 at 22:53
  • 2
    @s.bandara Why is it implicit? OP doesn't seem to even know about it. –  Feb 01 '13 at 22:54
  • @s.bandara I need it otherwise somebody will downvote this answer because it invokes undefined behavior ;) – ouah Feb 01 '13 at 22:55
  • That's what I thought, it looks like a CYA sentence, and I think it should go away. @H2CO3, if the goal is to inspect the memory allocated by `malloc` it is not even undefined behavior in that sense. Rather, the result will be undetermined, but so is the behavior of `scanf`, for example. – s.bandara Feb 01 '13 at 22:57
  • Indeterminate value doesn't mean undefined behavior. Does it? Sure you can read anything, but it won't cause your program to go crazy. – zch Feb 01 '13 at 22:59
  • @s.bandara Euh, no. It **is undefined behavior.** I do know the difference between undefined behavior and unspecified [behavior | result | value | order of evaluation]. And this **is** defined to invoke UB. –  Feb 01 '13 at 23:00
  • @s.bandara reading an indeterminate value invokes undefined behavior : *undefined behavior: Behavior upon use of a non portable or erroneous program construct of erroneous data or of indeterminately valued object* – ouah Feb 01 '13 at 23:01
  • Guys, all I have to say is that you should apply that definition in this particular context. You can look at memory before initialization using a debugger, which is doing exactly the same thing, but so what? "undefined behavior" is not meaningful in such a context. – s.bandara Feb 01 '13 at 23:04
  • @s.bandara but a debugger is not a C implementation, so undefined behavior does not apply to a debugger. – ouah Feb 01 '13 at 23:06
  • Strictly speaking, accessing an indeterminate value isn't always undefined behavior (and the above example isn't UB). C99 defines "indeterminate value" as "either an unspecified value or a trap representation". Since accessing memory through a character type cannot result in a trap representation, accessing an indeterminate value through a character type isn't undefined behavior - you'll just read unspecified values. – Michael Burr Feb 02 '13 at 01:22
  • 1
    @MichaelBurr strictly speaking reading an indeterminate value is always UB (so even if you read an `unsigned char` object and we know `unsigned char` objecst do not have trap representations). See DR#338 http:// http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_338.htm – ouah Feb 02 '13 at 01:36
  • @ouah: so I see that C11 (due to that DR) added UB behavior for reading though a character type in certain situations - however the 'new' UB only applies to accessing an automatic that has never had its address taken. A `malloc()`'ed block doesn't fall into that category. So I think that your example is still not UB. – Michael Burr Feb 02 '13 at 01:50
2

You can't - reading those bytes before initializing their contents leads to undefined behavior. If you really insist on doing this, however, try this:

void *buf = malloc(24);
unsigned char *ptr = buf;
for (int i = 0; i < 24; i++) {
    printf("%02x ", (int)ptr[i]);
}

free(buf);
printf("\n");
2
void print_memory(void *ptr, int size)
{ // Print 'size' bytes starting from 'ptr'
    unsigned char *c = (unsigned char *)ptr;
    int i = 0;

    while(i != size)
        printf("%02x ", c[i++]);           
}

As H2CO3 mentioned, using uninitialized data results in undefined behavior, but the above snipped should do what want. Call:

print_memory(p, 24);
Nik Bougalis
  • 10,495
  • 1
  • 21
  • 37
1

void* p = malloc(24); allocates 24 bytes and stores the address of first byte in p. If you try to print the value of p, you'll be actually printing the address. To print the value your pointer points to, you need to dereference it by using *. Also try to avoid void pointers if possible:

unsigned char *p = malloc(24);
// store something to the memory where p points to...
for(int i = 0; i < 24; ++i)
    printf("%02X", *(p + i));

And don't forget to free the memory that has been allocated by malloc :)

This question could help you too: What does "dereferencing" a pointer mean?

Community
  • 1
  • 1
LihO
  • 41,190
  • 11
  • 99
  • 167
0

malloc allocates in bytes and not in bits. And whatever it is, your printf is trying to print an address in the memory.

sr01853
  • 6,043
  • 1
  • 19
  • 39
0

The malloc allocates bytes.

 for (i = 0; i < 24; ++i) printf("%02xh ", p[i]);

would print the 24 bytes. But if cast to an int, you'll need to adjust the loop:

 for (i = 0; i < 24; i += sizeof(int)) printf("%xh", *(int *)&p[i]);

But then, if you know you want an int, why not just declare it as an int?

Gary
  • 243
  • 1
  • 8
  • I'll admit that no, I do not understand pointer arithmetic. I need to use a void pointer due to the specifications of a larger assignment. – kubiej21 Feb 01 '13 at 22:55
  • @kubiej21 I was directing this one to the author of this answer. –  Feb 01 '13 at 22:56
  • Ok, so a typo gets a snide remark? Are you sure you understand interacting with humans? – Gary Feb 05 '13 at 12:20