tags:

views:

148

answers:

5

Hello,

gcc 4.4.1 c89

I have the following code snippet:

#include <stdlib.h>
#include <stdio.h>

 char *buffer = malloc(10240);
 /* Check for memory error */
 if(!buffer)
 {
    fprintf(stderr, "Memory error\n");
    return 1;
 }
 printf("sizeof(buffer) [ %d ]\n", sizeof(buffer));

However, the sizeof(buffer) always prints 4. I know that a char* is only 4 bytes. However, I have allocated the memory for 10kb. So shouldn't the size be 10240? I am wondering am I thinking right here?

Many thanks for any suggestions,

+6  A: 

sizeof doesn't work on dynamic allocations (with some exceptions in C99). Your use of sizeof here is just giving you the size of the pointer. This code will give you the result you want:

char buffer[10240];
printf("sizeof(buffer) [ %d ]\n", sizeof(buffer));

If malloc() succeeds, the memory pointed to is at least as big as you asked for, so there's no reason to care about the actual size it allocated.

Also, you've allocated 10 kB, not 1 kB.

Carl Norum
This code is more than a little dangerous: it's allocating the buffer on the stack, not the heap. If you let any pointers to this buffer leak out of the function that declares it, you're on the way to stack corruption (and depending on how long your program runs, heap corruption and/or a segmentation fault).
Anon
@Anon - It's not dangerous, it just solves the problem a different way. The OP had no requirements about passing the buffer back from a function.
Chris Lutz
And what, exactly, is the OP's problem? Seems to me that it's keeping track of the size of a heap-allocated structure. Suggesting that the OP use a stack-allocated structure is not a solution to that problem.
Anon
+9  A: 

You are asking for the size of a char* which is 4 indeed, not the size of the buffer. The sizeof operator can not return the size of a dynamically allocated buffer, only the size of static types and structs known at compile time.

Péter Török
`sizeof` can return the size of a dynamic buffer for variable length arrays in C99.
Carl Norum
Is there any method under c89 that you can find how much memory has been allocated with a dynamically allocated buffer? Thanks.
robUK
@Carl - VLA's aren't dynamic. They're "variable length" in that their length can be computed at runtime, but not "variable length" in that their length can change. They're still stack-based arrays, which is why `sizeof` is defined to work for them.
Chris Lutz
@Carl, good point, I didn't know that. Thanks :-)
Péter Török
@robUK - Keep track of it yourself using a `struct { char *buf; size_t len; };`. Or use someone else's string library. Or maintain strict adherence to the "always pass lengths with buffers" rule (which you should probably do anyway).
Chris Lutz
@Carl. I have just tested your concept. I compiled with c99 i.e. -std=c99. However, sizeof still gave me the value 4.
robUK
@robUK - He means for C99 VLAs, i.e. `char c[/*runtime calc*/];` not dynamically allocated arrays, i.e. `char *c = malloc(/*runtime calc*/);`. And C99 VLAs are problematic and only spottily implemented and overall best avoided in my opinion.
Chris Lutz
@Chris, that's correct, and I agree with the recommendation to not use them.
Carl Norum
@robUK, there is no way to know how much memory `malloc()` actually gave you without other OS/library features that might be able to tell you. Those will be operating system/compiler dependent.
Carl Norum
I hope this is the last incarnation of this question. Its been asked numerous times before.
Tim Post
C99 VLAs are the most appropriate choice in many situations, and using them is far better than using the old nonstandard `alloca()`. If no-one uses them, the support will never improve.
caf
+3  A: 

It is up to you to track the size of the memory if you need it. The memory returned by malloc is only a pointer to "uninitialized" data. The sizeof operator is only working on the buffer variable.

Mark Wilkins
+1  A: 

Replace your sizeof by malloc_usable_size (the manpage indicates that this is non-portable, so may not be available with your particular C implementation).

Anon
`malloc_usable_size()` is very non-portable. I don't have it on OS X Leopard. Anyway, reliance on it is a terrible idea in the first place (as also stated in the manpage).
Chris Lutz
+3  A: 

No. buffer is a char *. It is a pointer to char data. The pointer only takes up 4 bytes (on your system).

It points to 10240 bytes of data (which, by the way, is not 1Kb. More like 10Kb), but the pointer doesn't know that. Consider:

int a1[3] = {0, 1, 2};
int a2[5] = {0, 1, 2, 3, 4};

int *p = a1;
// sizeof a1 == 12 (3 * sizeof(int))
// but sizeof p == 4
p = a2
// sizeof a2 == 20
// sizeof p still == 4

It's the main difference between arrays and pointers. If it didn't work that way, sizeof p would change in the above code, which doesn't make sense for a compile-time constant.

Chris Lutz