Get the length of dynamically allocated array in C [duplicate] - c

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

Related

Why does malloc() not allocate correct size of memory when using a pointer to `double`? [duplicate]

This question already has answers here:
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 6 years ago.
Here is the essence of what I am trying to do:
double *E; //Array of doubles
int N; //The eventual size of the array, typically >1
// some code where variable N gets assigned
//inside of some function
E = malloc(sizeof(double)*N);
printf("size of E = %lu\n",sizeof(E)/sizeof(E[0])); //checking size of array E
The output of this code is "size of E = 1", regardless of the actual value of N. Why does the malloc() function not allocate the correct size in memory?
I know this seems very rudimentary, but I cannot understand why this would not work.
Any insight would be greatly appreciated.
You are essentially dividing the size of the pointer by the size of a double. Both take the same amount of bytes (8 typically) to store. therefore you get 1.
E's type is pointer to double. E's value is an address. When you get the sizeof(E), you are getting the size of the variable that is the pointer rather than the size of what is being pointed to by the variable. In order to get the size of what malloc allocated, you need to dereference the pointer in sizeof so your last line becomes :
printf("size of E = %lu\n",sizeof(*E) * N/sizeof(E[0]));
EDIT
There is no difference between *E and E[0] as pointed out by one of the comments. In C, there is no way of you knowing where you array ends because the array itself as a datatype does not store its length. This is partly why the vector datatype in C++ was necessary.
Also, since you already stored the length of the array in N, you might as well just print N. When you pass the array to any functions, pass the array along with the length. With strings, you can get away with iterating over the character array till you get '\0', the null terminating character. For integer and floating point datatype arrays, there is no such convention.
malloc is allocating a right size array, else your test is wrong.
sizeof(E) is the size of the pointer = 8
sizeof(*E) is the size of the first double = 8
you can know the size of your array multiplying sizeof(*E) * N
To put another spin on this explanation, if sizeof(E) worked as you expected (giving the size of the allocated memory, rather than the size of the pointer) then you could use that to get the size of dynamically allocated arrays. You can't do that in C.

Using Sizeof and malloc function in C [duplicate]

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.

how to get the size of array using the pointer to this array in C? [duplicate]

This question already has answers here:
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 8 years ago.
I have the following code in C:
int array[5] = {0,1,2,3,4};
int * p = &array[0];
how to use the pointer p to get the size of this array p point to?
Sorry, this is actually impossible. The size of an array is not saved anywhere. You'll have to do it yourself.
It can't be done just from a pointer. The pointer is literally the address in memory of the first element of the array. The array size is not automatically associated with this pointer. You must keep track of the size yourself.
One workaround you can use is to reserve a special value for your array elements, say -1. If you can arrange for your last element to always have this value, then you can always find the end of the array by searching through it for that value. This is why strings have a null terminator, so strlen() and family can find the end of the string.
The short answer: In C, an array size cannot be retrieved from a pointer. The size must be passed separately.
The slightly-less-short answer: In C, a pointer is just an address to a spot in memory. The pointer does not even guarantee that there is a valid array or variable here; it is just a descriptor of a memory location.
In fact, in C, the concept of an array "size" is somewhat loose. A certain amount of consecutive memory can be allocated, but there is no checking as to if a pointer leaves this memory.
For example:
int a[] = {1, 2, 3};
int b = a[7];
will compile properly. C does not have any bounds checking!
you can not know the size of array using pointer to it. you cant determine since there is no way to know the end of array or to know that we reached the last element of array.
So, after reading 5 previous answers, here a better one:
a) You cannot get the element count of an array using a pointer.
Common workaround are:
Using a sentinel value (see C-String aka asciiz)
Passing the length separately. (see counted strings using mem*())
Actually using a struct, resp. reserving element 0 (or -1) for a lenght value. (also see counted strings).
Just allocate a whopping big amount of memory you know will suffice and not bother with the actual length at all. Getting this wrong is fun and easy to do.
b) You can get the element count of an array using the array name:
struct foo[my_expr];
ìnt count = sizeof array / sizeof *array;

C malloc allocated only 8 bytes for int * [duplicate]

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.

C pointers and arrays/ 'sizeof' operator [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Stack pointer difference for char pointer and array
To illustrate my question:
int main(void){
int myary[20];
int *myaryPtr;
myaryPtr = myary;
sizeof(myary); // Will it return 80? Correct?
sizeof(myaryPtr); // Will it return 4? Correct?
return 0;
}
First off, is my assumption correct?
And then assuming my assumption is correct, what is the detailed explanation? I understand that my 20 element array is 80 bytes, but isn't the name myary merely a pointer to the first element of the array? So shouldn't it also be 4?
Yes, your assumption is correct, assuming an int and a pointer are both 4 bytes long on your machine.
And no, arrays aren't pointers. The array name sometimes decays into a pointer in certain contexts, but they aren't the same thing. There is a whole section of the comp.lang.c FAQ dedicated to this common point of confusion.
The size of the array is not stored in memory in either case, whether you declare it as int myArr[20] or int* myArrPtr.
What happens is that sizeof() is replaced (by the compiler) with a constant value.
Therefore, because myArr was specified with a fixed size prior to compilation, the compiler knows just how big the amount of memory allocated is. With myArrPtr, you could dynamically allocate different array sizes, so only the size of the type is stored.

Resources