sizeof dynamic array is not correct [duplicate] - c

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 7 years ago.
In array there are four element so it size should be 4bit*4 = 16. (An int data type take 4 bit in my system to store the value.) But when i ran this code i only got 8 bit as the size of dynamicArray.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
//Dynamic arrays save memory by creating a pointer that stores
//the beginning of the array
int *dynamicArray = malloc(20 * sizeof(int));
*dynamicArray = 10;
printf("Address %x stores value %d\n", dynamicArray, *dynamicArray);
dynamicArray[1] = 20;
printf("dynamicArray[1] stores value %d\n", dynamicArray[1]);
dynamicArray[2] = 45;
printf("dynamicArray[2] stores value %d\n", dynamicArray[2]);
dynamicArray[3] = 34;
printf("dynamicArray[3] stores value %d\n", dynamicArray[3]);
printf("The size of dynamicArray is %d\n", sizeof(dynamicArray));
// Release unused memory:
free(dynamicArray);
return EXIT_SUCCESS;
}
Here is the image of output.
Also suggest me website for C to check the in-built function properties or to know about them more.
Thank you.

You don’t have an array; you have a pointer.
The size of the pointer is measured in bytes, not bits.
sizeof is evaluated at compile time and is constant for any given expression or type. It does not depend on the number of “filled” elements in an array (or pointer to some space that holds those elements, for that matter).
Your expression is equivalent to sizeof(int*), and pointers are 8 bytes in your environment.

I ran your code on my 32-bit computer and the value of sizeof(dynamicArray) does report 4. I bet your computer is 64-bits which is why the value is 8 instead.
Take a look at: http://www.viva64.com/en/a/0004/ and look for the table titled "Table N2. 32-bit and 64-bit data models.". That would help explain why some systems report 4 and some report 8 for the value for sizeof(dynamicArray).

Related

How to get array index by memory address in C? [duplicate]

This question already has answers here:
C - how to convert a pointer in an array to an index?
(1 answer)
Pointer subtraction confusion
(8 answers)
Do pointers support "array style indexing"?
(1 answer)
Closed 3 years ago.
This is my code, which can find highest number in an array by the pointer.
#define ELTS 5
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int i, *high, *p;
int array[ELTS]={200,34,78,600,45};
high=array;
p=array;
for ( i=1; i< ELTS; i++ ) {
p++;
if (*p > *high) high = p;
}
printf("the highest number is %d \n", *high);
printf("at address %p \n", high);
printf("index %ld \n", high);
printf("index %ld \n", array);
printf("at index %ld of array \n", high-array);
exit(0);
}
I also need to find the index number of this number, I did some research online. and find out I can use printf("at index %ld of array \n", high-array); to get the index of the highest number.
However, I don't understand how that works, can anyone explain it to me?
In high-array, high is the address of the element you are interested in, and array is the address of the first element in the array. (array actually identifies the array, but, when used in this expression, it is automatically converted to the address of the first element.) Then, with the - operator, the two addresses are subtracted.
When addresses are subtracted, C produces a result measured in units of array elements. So, even if the array addresses are measured in bytes, the compiler computes a result by subtracting the pointers (to get the difference in bytes) and then dividing by the number of bytes in an element (to get the difference in elements).
Thus, the result of high-array is the number of elements from the start of the array to the element pointed to by high, and that is the index of that element.
(In some C implementations, the pointers might not be measured in bytes and might not be simple one-number addresses. Regardless, the C implementation performs whatever operations are necessary to produce a result that is a number of elements.)
Notes
To print pointers, convert them to void * and print them with %p:
printf("index %p \n", (void *) high);
To print the difference of two pointers, use %td:
printf("at index %td of array \n", high-array);
Use the pointer arithmetic. The index is calculated like
high - array
The difference contains the number of elements of the type int between these two pointers.
Consider for example this statement from your program
p++;
After this statement the pointer points to the next element of the array. This statement can be rewritten like
int *q = p;
p = p + 1;
So p - q is equal to 1.

Segmentation fault error array in c [duplicate]

This question already has answers here:
Getting a stack overflow exception when declaring a large array
(8 answers)
Closed 4 years ago.
I want to write a program in which I want to initialize integer array of size 987654321 for storing values of 1 and 0 only,
here is my program
#include <stdio.h>
#include <stdlib.h>
int main(){
int x,y,z;
int limit = 987654321;
int arr[limit];
for (x = 0;x < limit;x++){
printf("%d \n",arr[x]);
}
return 0;
}
but it gives segmentation fault
987654321 is certainly too big for a local variable.
If you need a dynamically sized array of that size you need to use malloc like:
int limit = 987654321;
int *arr = malloc(limit * sizeof(*arr));
if (arr == NULL)
{
... display error message and quit
}
...
free(arr); // free it once you're dont with the array
BTW are you aware that your array uses roughly 4 gigabytes of memory assuming the size of int is 4 on your platform?
Since you want to store values of 1 and 0 only, and these values require only one bit, you can use a bit array instead of an integer array.
The size of int is 4 bytes (32 bits) usually, so you can reduce the memory required by a factor of 32.
So instead of about 4 GB, you will only need about 128 MB of memory. Resources on how to implement a bit array can be found online. One such implementation is here.

Sizeof(Array) Prints wrong value [duplicate]

This question already has answers here:
How do I determine the size of my array in C?
(24 answers)
Closed 6 years ago.
I have initialized an array of size 10 but on printing the sizof array shows 40 . The code is as follows ,
#include <iostream>
using namespace std;
int main() {
int arr[10] = {2,4,5,6,7,8,9,6,90};
printf("%d \n" , sizeof(arr));
}
Output :
/Users/venkat/Library/Caches/CLion2016.1/cmake/generated/InsertionSort-e101b03d/e101b03d/Debug/InsertionSort
40
Process finished with exit code 0
What does C prints 40 here ?
sizeofreturns the size of the array in memory, not the length of the array. Then since sizeof(int) is 4 bytes and your array has 10 int values, its size is 40.
Your array contain 10 ints.
10 * sizeof(int)
int here is 32 bits = 4 bytes.
4*10 = 40. Simple math
Because sizeof is a built in operator that works on the type of the expression. For arrays (and not pointers) it will print sizeof(array_element_type) * array_length.
On your system, it must be that sizeof(int) is 4.
And once you get excited over learning that
sizeof(array)/sizeof(array[0]) == array_length
bear in mind that once you pass the array into a function, it will decay to a pointer and that will no longer hold.
You need to divide sizeof (arr) by the size of one element:
sizeof (arr)/ sizeof (arr[0])
This because sizeof(arr) shows the number of bytes the argument is made of, i.e. sizeof(int) * array dimention

Pointers in C, theoretical aspect

I have programming exam soon, and I still can't understand some things, could you guys help me?
Basically, we got:
char *nap[]= {"Reklamacja","Perspektywa","Reinkarnacja","Hermengilda","Audytorium","Mineralogia","Frustracja"}
Those are bunch of words in Polish language, but they doesn't matter at all.
So moving on, we have:
Size of char type on this PC : 1
Size of long type on this PC : 4
Address of beginning nap array (char type): 0x22ff20
Address of R letter in word "Reklamacja": 0x47575d,
Address of P letter in word "Perspektywa": 0x475768,
Address of R letter in word "Reinkarnacja": 0x475774,
Address of H letter in word "Hermengilda": 0x475781,
Address of A letter in word "Audytorium": 0x47578e,
Address of M letter in word "Mineralogia": 0x475799,
Address of F letter in word "Frustracja": 0x4757a5
The question is: what is the effect of the following line of code?
printf("%#lx", nap+5);
The correct answer is: 0x22ff34
Why is it like so and not like 0x22ff20 + 5 which is 0x22ff25?
The answer is the same for any typed pointer value in C, and uses a language feature called pointer arithmetic.
What is the byte-width of the element type, including padding if a struct or union type?
Multiply by the index N you're using
Add to the base address of the array.
The result should be the address of the N'th element in the sequence. Note you cannot portably do this with void*, and any cast you perform on the pointer prior to performing the operation will affect the outcome.
In your case, the element type of your array is char *. Assuming sizeof(char*) == 4 on your platform then
4 bytes
4 * 5 = 20 bytes (0x14)
0x22ff20 + 0x14 = 0x22ff34
Remember, an array expresses as pointer-to-type with a value of the array base-address when used in the above calculation. It may seem trivial, but that is routinely the part of this that is missed.
Best of luck
nap is a pointer to the first item of the array: nap == &(nap[0]).
nap+5 is a pointer to the sixth item of the array: nap+5 == &(nap[5]).
Each item of your array is 4 bytes long (test for sizeof(char *)), so the numerical value of nap+5 is a numerical value of nap plus 5 times 4:
0x22ff20 + 4*5 = 0x22ff20 + 0x14 = 0x22ff34
Your nap variable is declared as a pointer to an array of strings. So when you are using nap+5 you are really moving the pointer 5 elements down the array (which will point to Mineralogia). In order to retrieve the result that you were expecting, you will have to cast the pointer so it will point to the first string, then add 5 to it to move the pointer 5 characters down. Here is a test application that I wrote up to demonstrate this (my code usually explains better than I can verbally lol):
#include <stdio.h>
int main()
{
char* nap[] = {"Reklamacja","Perspektywa","Reinkarnacja","Hermengilda","Audytorium","Mineralogia","Frustracja"};
//Returns the beginning address of nap
printf("%#lx\r\n", nap);
//Returns the sixth string in nap (aka nap[5] since arrays are 0-based index)
//and the address
printf("%s %#lx\r\n", *(nap+5), nap+5);
//Returns the first string in the array (aka nap[0]) and the address
printf("%s %#lx\r\n", *nap, *nap);
//Returns the 1st string in the array starting at the 6th letter and the address
printf("%s %#lx\r\n", *nap+5, *nap+5);
return 0;
}
Also remember that a char is 4 bytes so the last printf statement moved the pointer 20 bytes down the string.

Dynamic memory allocation and sizeof()

For allocating memory to two dimensional array dynamically, I write something like this
int **ar = (int **)malloc(row*sizeof(int*));
for(i = 0; i < row; i++)
ar[i] = (int*)malloc(col*sizeof(int));
I came across this code which does the same but i cannot understand the declaration.
double (*buf)[2] = (double (*)[2])malloc(count*sizeof(double [2]));// Explain this
printf("%d, %d, %d, %d \n",sizeof(double));
printf(" %d",sizeof(buf[0]));
printf(" %d", sizeof(buf));
//prints 8, 16, 16, 4 when count is 3
The output of first printf() is trivial. Please help me with the next two.
double (*buf)[2] = (double (*)[2])malloc(count*sizeof(double [2]));// Explain this
This
double (*buf)[2]
defines buf to be a pointer to an array of 2 doubles.
This
(double (*)[2])malloc(count*sizeof(double [2]));
can (and shall) be rewritten as
malloc(count * sizeof(double [2]));
The above line allocates memory with the size of count times "size for an array of 2 doubles".
This
=
assigns the latter to the former.
It all ends up with buf pointing to an array of count * 2 doubles.
Access its elements like this
(*buf)[0][0];
Note that this approach creates a pointer to a "linear" array, that is an array where all elements are store in one continues block of memory.
Whereas the approch you 1st mention in you question creates a "scattered" array that is an array where each row might be located in a seperate block of memory.
This
printf("%d, %d, %d, %d \n",sizeof(double));
provokes undefined behaviour, as from its 1st (format) parameter the printf expects four addtional parameters and is being passed only one.
The size of a double typically is 8.
This
printf(" %d",sizeof(buf[0]));
prints the size of the first element that buf points to. As buf points to an array of 2 doubles, it is expected to print 2 times "size of a double" which 2 * 8 = 16.
This
printf(" %d", sizeof(buf));
prints the size of buf. As buf is defined as a pointer, the size of a pointer on is printed. This typically is 4 for a 32bit implementation and 8 for 64bit implementation.
Note: The value of count does not appear in any of the sizes printed above, not directly, nor indireclty, as In C it is not possible to derive from a pointer how much memory had been allocated to it.

Resources