1

I am running this piece of code on a hardware.

unsigned char *buf;

buf = malloc(sizeof(int));
printf("Address of buf %d\n" , &buf);

if(!buf)
    return MEMORYALLOC_FAILURE;

The malloc is returning negative value. What could be the problem?

user7116
  • 63,008
  • 17
  • 141
  • 172
  • Malloc doesn't return "negative" values. It returns an address (inherently unsigned), which could appear to be negative when printed as a signed integer. Also you aren't printing the address returned from `malloc`. You're printing the address where the pointer is stored. Remove the '&' to print the value from malloc. Malloc will return NULL on failure. So to be safe, your if should really say `if( buf == NULL )` although you're unlikely to run into a compiler where `!buf` causes problems. – Brian McFarland Mar 07 '12 at 18:13
  • 1
    @BrianMcFarland In fact, per the standard, `!buf` is equivalent to `buf != NULL` - (6.5.3.3) and (6.5.9) in n1570. – Daniel Fischer Mar 07 '12 at 18:57
  • @DanielFischer: On certain [old/esoteric platforms](http://stackoverflow.com/questions/2597142/when-was-the-null-macro-not-0), `NULL != 0`. [Others argue strongly against the explicit comparison against null](http://stackoverflow.com/questions/5187692/is-there-a-pragmatic-reason-to-use-if-0-p-instead-of-if-p). I think its a matter of style, but one style is slightly more prone to becoming a portability issue than the other. – Brian McFarland Mar 07 '12 at 19:44
  • @BrianMcFarland But `0` is a null pointer constant, as is `NULL`, so 1) no valid pointer to an object compares equal to either `0` or `NULL`, 2) all null pointers compare equal to both `0` and `NULL`, 3) `NULL == 0` must evaluate to true in all conforming implementations. Whether a null pointer is all bits 0 is an entirely different question (quite interesting, though, if all bits 0 is a valid address you want to write to). As to explicit comparisons to `NULL` instead of implicit, I have no preference. Both are correct and perfectly readable. – Daniel Fischer Mar 07 '12 at 20:11

5 Answers5

10

Address returned by malloc is not negative or positive, it just address, use %p to print it, not %d:

printf("Address of buf %p\n" , &buf);

And if you want to print the address returned from malloc, remove the ampersand:

printf("Address of buf %p\n" , buf);
MByD
  • 135,866
  • 28
  • 264
  • 277
4

You're printing the address of a memory location as a signed integer. If the memory address--for example on a 32bit machine--is more than 2,147,483,647 (0x7FFFFFFF) it will display as a negative number.

In this case you're also printing the address of a local variable on the stack rather than the address returned by malloc.

The error with using %d to print a pointer-sized value is that pointers may vary in size. The correct approach therefore would be to use the printf specifier for pointers, %p:

// nb: we don't take the address of buf,
// buf is already a pointer (thus its *value* is an address)
printf("Address of buf %p\n", buf);                                   
user7116
  • 63,008
  • 17
  • 141
  • 172
2

Type mismatch:

you try to print an address with the specifier for an int ("%d"). You should use "%p" and cast the value to void*

printf("Address of buf %p\n" , (void*)&buf);

Also note the above will not tell you where the allocated memory is. For that you'd need

printf("Address of newly allocated memory %p\n" , (void*)buf);

The cast to void* is mandated by the C99 standard (emphasis is mine)

The argument shall be a pointer to void. The value of the pointer is converted to a sequence of printing characters, in an implementation-defined manner.

Also note that pointers to void need not have the same representation as pointers to other types.

pmg
  • 106,608
  • 13
  • 126
  • 198
  • In this case it is not accurate, as stated in the same document: "A pointer to void shall have the same representation and alignment requirements as a pointer to a character type" also look at note 39 there. – MByD Mar 07 '12 at 18:36
  • Ok, pointers to char and pointers to void have the same representation and alignments requirements: the cast is required only for the first example ... but **always** using the cast, even when redundant, is safer than using it only when required. – pmg Mar 07 '12 at 18:44
1

malloc returns either NULL (aka 0) or a memory address. Memory addresses cannot be negative. You just converted the pointer itself to a number, resulting in a negative number.

0

malloc returns a pointer. It never returns a negative value. If you think it is then you probably have a broken everything. On the other hand if you mean it returns a null pointer, then it means you are unable to allocate that memory.

Dan
  • 10,531
  • 2
  • 36
  • 55