Dynamic memory allocation and sizeof() - c

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.

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.

Code to print the no of elements in an array gives one less than the no of elements

I've written a code to find the number of elements in an integer array as follows:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int arr[] = {2, 3, 5, 5};
int i;
for(i = 0; i < 4; i++)
{
printf("%d %d\n", &arr[i], arr[i]);
}
printf("%d", &arr[i - 1] - arr);
return 0;
}
The last printf prints 3 as opposed to 4 which is the number of elements in the array. Why does the code print one less than the no of elements in the array?
You pass the wrong format specifier to printf. So whatever output you get in the loop is the result of undefined behavior. To print a pointer correctly and portably you must use the %p specifier and pass a void*:
printf("%p %d\n", (void*)&arr[i], arr[i]);
The reason the last printf prints 3 (even though the format specifier is maybe wrong again), is because that's the offset between the the last cell in the array and the beginning. That's what you calculate, so remember that the last cell is indexed with offset 3.
The result of subtracting two pointers can be captured in the type ptrdiff_t. And to print that you'd need the %td format specifier, if we are to make your code more portable again:
printf("%td", &arr[i-1]-arr);
To calculate the array length, you'd need to subtract a pointer to "one passed the end" element of the array (don't worry, calculating that address is not undefined behavior) and a pointer to the beginning. Applying that to the print statement after your loop
printf("%td", (arr + i) - arr);
Which quite expectantly, is just i (4).
Your last printf need correction for specifiers as in your case the difference in first and last position address can easily fit in int but caan produce undefined behaviour so use td specifier as difference in address is of ptrdiff_t type. The problem is that how you calculate your length of array, keep in mind that indexing is done from zero that is if you have array length of 4, last index would be 3 and
array length according to your code is 3 - 0 = 3
but actually it should be 3 - 0 + 1 = 4
change your outside printf to
printf("%td",&arr[i-1] - arr + 1);
I hope this would help you. Also you printf in your for loop needs correct specifier as you are trying to print the address instead of int.

sizeof dynamic array is not correct [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 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).

Pointer not printing in the desired way

This is a C code
int (*a)[3];
a is a pointer to an array of 3 integers
a=(int (*)[3])malloc(sizeof(int)*3);
note the Typecast used here; the number of elements must be specified in the typecast shown. Also, the brackets around the * is necessary.
printf("brrbrrbrr %d %d %d %d\n",&a,a,a+1,a+2);
*(a+0)[0]=40;
*(a+0)[1]=41;
*(a+0)[2]=42;
printf("noobnoob %d %d %d \n",a[0][0],*(a+0)[1],(*(*(a+0)+2)));
The output is:
brrbrrbrr -7077000 29278656 29278668 29278680
noobnoob 40 41 0
I am not getting why the last number is 0 instead of 42?
Indexation has higher precedence than dereferencing a pointer. Your assignments don't do what you want. They are evaluated like:
*((a+0)[0])=40;
*((a+0)[1])=41;
*((a+0)[2])=42;
If you want to keep your syntax, you shall use parenthesis like:
(*(a+0))[0] = 40;
(*(a+0))[1] = 41;
(*(a+0))[2] = 42;
The same applies for printing the second element of the array. *(a+0)[1] shall be (*(a+0))[1].
What you are looking for is
int (*a)[3] = malloc(sizeof(int) *3);
(*a)[0] = 40;
(*a)[1] = 41;
(*a)[2] = 42;
printf("%d %d %d\n",(*a)[0],(*a)[1],(*a)[2]);
a is a pointer to an array of 3 int members. So allocate memory for the pointer and store values as shown above.
If you want the address of where the values are stored then you should do
printf("%p\n",(void*)(a)[0]);

int* vector accepts only the first given value

I'm experiencing some troubles with my code written in C. It's all about an int * vector intially declared and dynamically allocated but when it comes to filling it with data it stuck on the first element and won't increment the counter to fill the rest of the vector
my header file : instance.h
struct pbCoupe
{
int tailleBarre;
int nbTaillesDem;
int nbTotPcs;
int * taille;
int * nbDem;
};
my code : coupe.c
pb->taille = (int*) malloc (pb->nbTaillesDem * sizeof(int));
pb->nbDem = (int*) malloc (pb->nbTaillesDem * sizeof(int));
while (i < pb->nbTaillesDem)
{
fscanf_s(instanceFile,"%s",data,sizeof(data));
pb->taille[i] = atoi(data); //<-- here is the problem !! it only accept the first value and ignore all the rest
printf("%s\n",data);
fscanf_s(instanceFile,"%s",data,sizeof(data));
pb->nbDem[i] = atoi(data); //<-- the same problem here too !!
printf("%s\n",data);
i++;
}
Your interpretation of sizeof is wrong, since data is the buffer that the string is being parsed into.
It returns the size of the the variable, not the size of the the what the variable (or namely a pointer) points to
Strings in C are all pointer to the size would be 4 bytes on a 32-bit system, 8 on a 64-bit.
Since it prints all the number it reading more numbers that intended with each loop iteration 4 bytes = 4 characters, atoi on parses the first integer and returns,
EDIT: If it is a buffer array, sizeof returns the size of the array.
You need to make sure you are only reading in a single number per iteration of the loop to solve this issue.
If you don't care for the literal string, best thing you can do is use:
fscanf(instanceFile, "%d", ((pb->taille) + i)));
//and store the integer into the index right away
//last param same as &pb->taille[i]

Resources