Saw this in an answer to another question:
char (*arrs)[rowSize] = malloc(bytesPerTable);
What is arrs? / why are there parentheses / what is the description of this declaration?
What is arrs ? what is the description of this declaration?
It's a pointer to an array of rowSize chars, vastly different from a pointer to a char.
why are there parentheses
Because without them it would be an array of pointers to char.
int *a[10] - This means, a is an array of 10 elements and the element type is int * Size of variable a will be 40 bytes in 32 bit machine or 80 bytes in 64 bit machine.
int (*a)[10] - This means, a is a pointer variable and its size will be 4 bytes(or 8 bytes), which can hold address of a int array of size 10 like below.
int (*a)[10] = NULL;
int b[10] = {0};
a = &b;
Related
I dont understand why the output of this code is 4 and not 16, Assuming that unsigned int takes 4 bytes and long int takes 8 bytes. Any help?
#include <stdio.h>
struct test {
unsigned int x;
long int y : 33;
unsigned int z;
};
int main()
{
struct test t;
unsigned int* ptr1 = &t.x;
unsigned int* ptr2 = &t.z;
printf("%d", ptr2 - ptr1);
return 0;
}
I assume you expected the output to be 16, because the offset between the pointers should be 16 bytes (assuming sizes are as you mentioned in your question).
But in c when you subtract pointers, you don't get the number of bytes but the number of elements. The elements are the data the pointers point to.
Since these are unsigned int pointers, and assuming sizeof(unsigned int) is 4, the difference between thr pointers is 4 elements.
However - as #Lundin commented above this theoretical claculation is not really relevant because subtrating pointers that do not point the same array is UB (undefined behavior).
BTW - Note when you add an integral value to a pointer, a similar thing happens on the other way: the result is the address of the pointer plus the integral value times the size of the element pointed by the pointer. E.g.: if you add 1 to unsigned int* ptr1, the resulting address will be higher than ptr1 by 4.
I know this would not work, because I cannot make arithmetic on void:
int main (void) {
void *ar = malloc(25); //adress of int + adr of char + adr of int = 3 * 8 + 1 null
int a =4;
int b =6;
*(ar+0)=&a //adr of first int - 8 bytes
*(ar+8)="abc\0"; // adr of the first char - 8 bytes
*(ar+16)=&b; // adr of the second int - 8 bytes
ar[24] = NULL;
return 0;
}
So the question is , how to make an buffer with arbitrary type, only according to its byte width (specifically the buffer in this case would contains 3 addresses of arbitrary types, but that should not matter, since all addresses are 8 bytes long)?
How how to enable to compiler to do arithmetic on (void*), according to programmers intend? (because I specify how long of the buffer I want to move forward to reach the first byte to start at).
Specify the type as a pointer to a pointer to void (or as an array of pointers). The compiler knows the size of a pointer to void, allowing you to perform arithmetic as per usual.
On the stack:
void *arr[3];
Dynamically:
void **arr = malloc(sizeof(void*)*3);
Usage:
int a = 10, b = 20, c = 30;
arr[0] = &a;
arr[1] = &b;
arr[2] = &c;
A simple C program:
#define MAXROW 2
#define MAXCOL 2
int main()
{
int (*p)[MAXROW][MAXCOL];
printf("%d\n",sizeof(*p));
return 0;
}
The answer is 16.
I don't understand how.
It follows this rule:
size = number of elements * sizeof (pointer variable, i.e 4)
Can anybody tell me how to analyse this expression so that the answer become obvious?
sizeof(int) = 4 on your machine.
p is an array pointer pointing at a 2D array of 2*2 int.
sizeof(*p) gives the size of the type that p can point to, i.e. the size of the array.
The size of the array = 2*2*4 = 16.
You have
int* p[MAXROW][MAXCOL];
and call sizeof(*p), which is the size of an array of integer arrays
so *p is:
int[2][2]
and
sizeof(*p) == sizeof(int) * 2 * 2
An example to explain pointer and arrays:
int a = 2; //a is an integer with the value 2
sizeof(a); //4 because an integer on your system does probably have 4 Byte
int b[2] = {1, 2};
int *c = b; //1d array
assert(sizeof(b) == sizeof(c)); //size of 1d array = size of 2 integers = 8 Byte
assert(sizeof(*c) == sizeof(b[0]));// size of 1 integer = 4 Byte
I have a problem where I have a pointer to an area in memory. I would like to use this pointer to create an integer array.
Essentially this is what I have, a pointer to a memory address of size 100*300*2 = 60000 bytes
unsigned char *ptr = 0x00000000; // fictional point in memory goes up to 0x0000EA60
What i would like to achieve is to examine this memory as an integer array of size 100*150 = 15000 ints = 60000 bytes, like this:
unsigned int array[ 100 ][ 150 ];
I'm assuming it involves some casting though i'm not sure exactly how to formulate it. Any help would be appreciated.
You can cast the pointer to unsigned int (*)[150]. It can then be used as if it is a 2D array ("as if", since behavior of sizeof is different).
unsigned int (*array)[150] = (unsigned int (*)[150]) ptr;
Starting with your ptr declaration
unsigned char *ptr = 0x00000000; // fictional point in memory goes up to 0x0000EA60
You can cast ptr to a pointer to whatever type you're treating the block as, in this case array of array of unsigned int. We'll declare a new pointer:
unsigned int (*array_2d)[100][150] = (unsigned int (*)[100][150])ptr;
Then, access elements by dereferencing and then indexing just as you would for a normal 2d array.
(*array_2d)[50][73] = 27;
Some typedefs would help clean things up, too.
typedef unsigned int my_2d_array_t[100][150];
typedef my_2d_array_t *my_2d_array_ptr_t;
my_2d_array_ptr_t array_2d = (my_2d_array_ptr_t)ptr;
(*array_2d)[26][3] = 357;
...
And sizeof should work properly.
sizeof(array_2d); //4, given 32-bit pointer
sizeof(*array_2d); //60000, given 32-bit ints
sizeof((*array_2d)[0]); //600, size of array of 150 ints
sizeof((*array_2d)[0][1]); //4, size of 1 int
The output of following program
#include<stdio.h>
int main(){
int *p[10];
printf("%ld %ld\n",sizeof(*p),sizeof(p));
}
is
8 <--- sizeof(*p) gives size of single element in the array of int *p[10]
80 <--- sizeof(p) gives size of whole array which is 10 * 8 in size.
now see the following program
#include<stdio.h>
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};
int main()
{
int d;
printf("sizeof(array) = %ld \n",sizeof(array));
printf("sizeof(array[0]) = %ld \n",sizeof(array[0]));
printf("sizeof int %ld\n",sizeof(int));
printf("TOTAL_ELEMENTS=%ld \n",TOTAL_ELEMENTS);
for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
printf("%d\n",array[d+1]);
return 0;
}
is
sizeof(array) = 28
sizeof(array[0]) = 4 <--here
sizeof int 4
TOTAL_ELEMENTS=7
What I am not able to understand is why is the sizeof(array[0]) different in both the outputs.
int *p[10];
is an array of pointers.
*p
is the first element of that array of pointers. So it is a pointer to an integer. It is not an integer.
int array[] = {23,34,12,17,204,99,16}; is an array of integers. So array[0] is the first element of that array. So it is an integer.
The size of a pointer to an integer (*p) and an integer (array[0]) are different.
So sizeof(*p) and sizeof(array[0])
are different.
sizeof(p) gives the size of the array of pointers. So it is: 10 x 8 = 80.
i.e. (number of elements) x (size of one element)
sizeof(array) gives the size of the array of integers. So it is: 7 x 4 = 28.
In the first example, the element is a pointer to int, while in the second example it's just int. You can see that the pointer has 8 bytes, the int just 4 bytes.
In the first case, you've created an array of pointers to int, so their size is 8, not 4.
In the first example the size of a pointer is used and in the second the size of an integer. They may have different sizes especially on 64 bit systems.
array[0] has type int
*p has type int*
This perhaps demonstrates the stylistic folly of writing
int *p[10] ;
rather than
int* p[10] ;
where the second makes it clearer that int* is the type of the array being declared.
The 64-bit environment sets int to 32 bits and long and pointer to 64 bits ..
*p is a pointer - 8 bytes
sizeof(p) -is size of 10 pointers - so 80 bytes
Chances are you have AMD64 machine - check this for details (including other options)
http://gcc.gnu.org/onlinedocs/gcc/i386-and-x86_002d64-Options.html