This question already has answers here:
size of a pointer allocated by malloc [duplicate]
(4 answers)
Closed 9 years ago.
I'm trying to create a pointer to a 6 element int in a function to return it later, so for that purpose I'm using malloc, but it seems to be acting not as I expected. Here's the code:
int j = 0;
for (;j < 5; j++) {
int * intBig = malloc(j * sizeof(int));
printf("sizeof intBig - %ld\n", sizeof(intBig));
}
Prints the same number 8 bytes as the sizeof(intBig) at each iteration. Whereas I would expect a series of 4, 8, 12, 16. What am I missing in this instance?
This is because you're printing the size of an int *. Such a pointer always has the same size. sizeof is a compiler construct. It cannot know things that only occur at runtime, such as dynamic memory allocation. Would it be something like
int intBig[100];
then you would get the size of the array back (in bytes), because the compiler knows how large it is. But the result of the sizeof operator is always a compile-time constant¹, so there is no way what you have there could yield anything else.
Besides, you have a memory leak there because you're not free-ing your memory again.
¹ Variable Length Arrays (VLA) are an exception, but they were not used here.
You cannot use sizeof to figure out the size of a memory block returned from malloc().
Except for variable length arrays in C99 and later, sizeof works only on statically known sizes.
Because every time you are printing the size of a pointer which is the size of an address which is 8 bytes.
sizeof tells you the size of the pointer intBig, not what it points to.
There's no standard way to discover the size of the memory block it points to, so you have to remember that separately.
If you have access to C++, just use std::vector for your dynamic array needs... it knows its size and doesn't forget to deallocate.
Related
This question already has answers here:
Using sizeof() on malloc'd memory [duplicate]
(5 answers)
Closed 6 years ago.
For the following C code, I expect the last printf to print "10,10" when I input only one character. Instead it prints "10,8". Why is input only 8 bytes when I malloc 10 bytes?
char* input;
unsigned long inputLen = 10;
input = (char*) malloc(10 * sizeof(char));
printf("Input: ");
getline(&input,&inputLen,stdin);
printf("%lu,%d",inputLen,sizeof(input));
sizeof(input) returns the size of the pointer input, which is 8 bytes.
Via the C FAQ:
Q: Why doesn't sizeof tell me the size of the block of memory pointed to by a pointer?
A: sizeof tells you the size of the pointer. There is no portable way to find out the size of a malloc'ed block. (Remember, too, that sizeof operates at compile time, and see also question 7.27.)
If you want to keep track of the capacity of input, you need to use a separate variable, or declare input on the stack as an array, and divide the size of the array by the size of an individual element of the array. It's almost always easier just to preserve the capacity as a separate variable.
Why is input only 8 bytes when I malloc 10 bytes?
Because input is a pointer and pointers are 8 bytes on your platform. The sizeof function just tells you the size of the type, determined at compile time.
It's because input is a char*. You should consider using strlen provided you null terminate it.
This question already has answers here:
Newbie questions about malloc and sizeof
(8 answers)
Closed 7 years ago.
I've just been playing around in C for the first time, and I'm at a loss as to why malloc is not giving me the amount of memory that I'd expect it to. The following code:
printf("Allocating %ld bytes of memory\n", 5*sizeof(int));
int *array = (int *) malloc(5*sizeof(int));
printf("%ld bytes of memory allocated\n", sizeof(array));
results in:
Allocating 20 bytes of memory
8 bytes of memory allocated
I've checked that I'm indeed calling malloc to give me 20 bytes, but don't understand why after calling malloc, the pointer only has 8 bytes.
array is not an array but an int *. So it's size will always be the size of the pointer.
The sizeof operator does not tell you how much memory was dynamically allocated at a pointer.
If on the other hand you had this:
int array2[5];
Then sizeof(array2) would be 20, assuming an int is 4 bytes.
The sizeof operator tells you the size of its operand. array has type int* (pointer to int) which occupies eight bytes on your platform. The sizeof operator cannot find out how long the array array points to actually is. What is returns is not indicative about how much memory has been allocated.
The malloc() function either fails (in which case it returns NULL) or succeeds in which case it returns a pointer to a memory region at least as large as you need it.
This question already has answers here:
Newbie questions about malloc and sizeof
(8 answers)
Closed 7 years ago.
I am a newbie to C,
My Problem is the following code,
int Max[10],*New_Max;
int length=5;
New_Max=(int)malloc(sizeof(int)*length));
printf("sizeof(Max)=%d,sizeof(New_Max)=%d",sizeof(Max),sizeof(New_Max));`
Output:
sizeof(Max)=40,sizeof(New_Max)=4
I Expect sizeof(New_Max) to be 20, but it prints as 4.
Can anyone explain the reason for it.
The following line allocates memory to what New_Max is pointing.
New_Max=(int)malloc(sizeof(int)*length));
And, the following line grabs the info about what a pointer size is :
sizeof(New_Max)
So, the size of what pointer is pointing and its own size are two different things. That's why you are getting size of New_Max to be 4.
You are making wrong assumption, that sizeof behaves in the same way for both types of memory allocation. There is fundamental difference between array and pointer and how it relates to sizeof. If you provide it with array, like here:
int Max[10];
size_t size = sizeof(Max);
then you will get overall size, that is number of elements multiplied by size of each element, that is:
10 * sizeof(Max[0])
On the other hand, for pointers, it results into size of pointer itself, not taking any elements into account, thus what you get is just sizeof(int *). It does not matter if it points to NULL or some array object, the size would be the same.
Note that, the proper format specifier for sizeof is %zu, not the %d.
I am curious why I am getting the following behaviour in my code.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int M=24;
int arr[M];
int N=24;
int* ptr=(int*) malloc(sizeof(int)*N); /*Allocate memory of size N */
printf("Size of your malloced array is %lu\n",sizeof(ptr)/sizeof(ptr[0])); /* Get the size of memory alloctaed. Should be the same as N?*/
printf ("Size of your normal arrays is %lu\n",sizeof(arr)/sizeof(arr[0])); /* Ditto */
free(ptr);
return 0;
}
The output is
Size of your malloced array is 2
Size of your normal arrays is 24
I would have thought the output would be 24 in both places. How then does one get the size of the malloced array If somehow I have "forgotten" it?
Surely the pointer ptr will contain some information about the size of the malloced array since when we call free(ptr) it will release the array just malloced
When you use sizeof() on a pointer, you get the size of the pointer. Not the size of the allocated array. In your case, a pointer is probably 8 bytes and an int is 4 bytes, hence why you get 2.
In short, you can't get the size of an allocated array. You need to keep track of it yourself.
EDIT : Note that some compilers do actually support this functionality as an extension:
For example, MSVC supports _msize(): http://msdn.microsoft.com/en-us/library/z2s077bc.aspx
While sizeof() works as you'd expect with fixed-length and variable-length arrays, it doesn't know anything about the sizes of malloc()'ed arrays.
When applied to a pointer, sizeof() simply returns the size of the pointer.
More generally, given a pointer to a malloc()'ed block, there's no standard way to discover the size of that block.
See C FAQ questions 7.27 and 7.28.
In summary, if you need to know the size of a heap-allocated array in a portable manner, you have to keep track of that size yourself.
You cannot obtain, at runtime, the size of an array if you only have a pointer to (the first element of) the array. There are no constructs at all in C that allow you to do this. You have to keep track of the length yourself.
If you happen to have an array rather than a pointer then you can find its length, but not for a pointer to an element of the array.
In your code, ptr is a pointer and so you cannot find out the length of the array to which it points. On the other hand, arr is an array and so you can find out its length with sizeof(arr)/sizeof(arr[0]).
As this other question points out, there is no portable way getting the size of a dynamic array, since malloc may allocate more memory than requested. Furthermore managing malloc requests is up to the operating system. For instance *nix would calls sbrkand store the requests somewhere. So, when you call sizeof(ptr) it returns the size of the pointer and not the size of the array. On the other hand, if your array is fixed, the size of it is determined at compile time, so the compiler is able to replace sizeof(arr) with the size of the fixed array, thus providing you the "correct" size.
The size of a pointer is 4 bytes on 32-bit machines and 8 bytes on 64-bit machines. I guess you work on a 64-bit machine since the size of an int is 4, and you got that sizeof(ptr)/sizeof(ptr[0]) is 2.
The thing to remember about sizeof is that it is a compile-time operator1; it returns the number of bytes based on the type of the operand.
The type of arr is int [24], so sizeof arr will evaluate to the number of bytes required to store 24 int values. The type of ptr is int *, so sizeof ptr will evaluate to the number of bytes required to store a single int * value. Since this happens at compile time, there's no way for sizeof to know what block of memory ptr is pointing to or how large it is.
In general, you cannot determine how large a chunk of memory a pointer points to based on the pointer value itself; that information must be tracked separately.
Stylistic nit: a preferred way to write the malloc call is
int *ptr = malloc(sizeof *ptr * N);
In C, you do not need to cast the result of malloc to the target pointer type2, and doing so can potentially mask a useful diagnostic if you forget to include stdlib.h or otherwise don't have a prototype for malloc in scope.
Secondly, notice that I pass the expression *ptr as the operand to sizeof rather than (int). This minimizes bugs in the event you change the type of ptr but forget to change the type in the corresponding malloc call. This works because sizeof doesn't attempt to evaluate the operand (meaning it doesn't attempt to dereference ptr); it only computes its type.
1 The exception to this rule occurs when sizeof is applied to a variable-length array; since the size of the array isn't determined until runtime, a sizeof operator applied to a VLA will be evaluated at runtime.
2 Note that this is not the case in C++; a cast is required, but if you're writing C++ you should be using new and delete instead of malloc and free anyway. Also, this is only true since C89; older versions of C had malloc return char * instead of void *, so for those versions the cast was required. Unless you are working on a very old implementation (such as an old VAX mini running an ancient version of VMS), this shouldn't be an issue.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
length of array in function argument
How do I get the length of a dynamically allocated array in C?
I tried:
sizeof(ptr)
sizeof(ptr + 100)
and they didn't work.
You can't. You have to pass the length as a parameter to your function. The size of a pointer is the size of a variable containing an address, this is the reason of 4 ( 32 bit address space ) you found.
Since malloc just gives back a block of memory you could add extra information in the block telling how many elements are in the array, that is one way around if you cannot add an argument that tells the size of the array
e.g.
char* ptr = malloc( sizeof(double) * 10 + sizeof(char) );
*ptr++ = 10;
return (double*)ptr;
assuming you can read before the array in PHP, a language which I am not familiar with.
Here you see the dangers of C: a ptr just points to memory and has no way of knowing what supposed size is. You can just increment and increment and the OS might complain eventually, or you crash your program, or corrupt other ones. You should always specify the size, and check bounds yourself!
This is similar to Using pointer for crossing over all elements in INTEGER array
See my answer here