why value a and x is different? I think it should be the same
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int a =5;
int *x=&a;
printf("%ld\n", sizeof(a)); // print 4
printf("%ld\n", sizeof(x)); // print 8
return(0);
}
I am not sure whether you are aware of what you are actually measuring with the sizeof operator.
First you measure integer a, which is the size of an int (4 bytes).
And second you measure not an integer but a pointer which stores the address of integer a, so the value is different and I think the value of x is 8 bytes.
int a (4 bytes INTEGER)
int *x = &a (is address of a)
But I can be wrong.
why value a and x is different? I think it should be the same
a is an int and x is a pointer.
int a = 5;
int *x = &a;
C does not specifier an int and a pointer need to be the same size. They may have the same size. Commonly a pointer is as wide as an int or wider, yet either one may be wider than the other.
It is implementation defined.
Since C99, use "%zu" to print a size_t, which is the resultant type from sizeof.
// printf("%ld\n", sizeof(a));
printf("%zu\n", sizeof(a));
// or
printf("%zu\n", sizeof a); // () not needed about objects.
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 wrote a pretty simple piece of C code:
int main(void) {
void *area = malloc(2 * sizeof(int));
unsigned int *int_one = (unsigned int *) area;
unsigned int *int_two = ((unsigned int *) area) + 3;
*int_two = 4293422034;
*int_one = 2;
printf("%u\n%u\n", *int_two, *int_one);
return 0;
}
sizeof(int) is 4 on my machine. Per my understanding, shouldn't the modification of memory at address int_one have an effect on the value stored at address int_two?
Modifying *int_one alters the first 4 bytes of mem. address area (perhaps not all 4, but enough to warrant the result I'm expecting?), and the integer at address int_two starts at the last byte of integer int_one.
So, shouldn't changing memory at int_one have an effect on memory at int_two?
Yet the printf call produces 4293422034 and 2 respectively.
I made sure to use unsigned variables to avoid confusion around 2s complement and negative values, and to use a small value for *int_one to warrant the change of its last byte (don't know if this is right?)
What am I not getting?
Operator '+', when applied to a pointer, increases the pointer n times the size of the object it points to. So increasing an int* by 3 does not add 3 bytes but 3*sizeof(int) bytes.
Pointer arithmetic is scaled by the size of the type the pointer points at. (sizeof(unsigned int) in your case). You'd need to cast to (char*) before adding 3 if you want to increase the address by 3 bytes, but converting that to an unsigned* pointer would incur undefined behavior by violating alignment requirements (6.3.2.3p7) and dereferencing the pointer would make the program even "more undefined" by violating strict aliasing rules (6.5p7).
To realy do this kind of type punning right, you'd need to use memcpy (or unions).
Example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
void *area = malloc(2 * sizeof(int));
if(!area) return EXIT_FAILURE;
unsigned int *int_one_p = area;
void *int_two_p = (((char*) area) + 3); /*saving this to an (unsigned*) would be UB*/
memcpy(int_two_p,&(unsigned){4293422034},sizeof(unsigned));
memcpy(int_one_p,&(unsigned){2},sizeof(unsigned));
unsigned one,two;
memcpy(&one,int_one_p, sizeof(one));
memcpy(&two,int_two_p, sizeof(two));
printf("%u\n%u\n", two, one);
return 0;
}
This question already has answers here:
Stack pointer difference for char pointer and array
(1 answer)
C pointers and arrays/ 'sizeof' operator [duplicate]
(2 answers)
Closed 9 years ago.
Hi i was doing this exercise and wanted to get the size of array after i pass the pointer to the array to the function:
But the sizeof() operator doesn't work on pointer but works on the array name. Why is it so?
Is this any way i could get the size of the array on the findPut function?
#include <stdio.h>
//global vars
int i,j;
//functions prototypes
void findPut(int *, int);
int main(void){
int ins=4;
int arr[10]={1,2,3,5,6,7,8};
printf("%d\n",sizeof(arr)); //gives 40
int *ap=arr;
printf("%d\n",sizeof(*ap)); //gives 4 instead of 40 why?? if ap and arr the same thing
findPut(ap, ins);
return 0;
}
//functions
void findPut(int *p, int n){
//vars
//getting size of array
int size= sizeof(*p);
//sizeof(int);
printf("%d\n",size); //gives 4 but expected 40????
}
When you dereference *p you get an int, so it returns 4 (which is the size of int on your platform).
Because, sizeof(*ap) means sizeof(arr[0]); since array is of type int, sizeof(int), since in your system configuration, int is of size 4 you got the result as 4.
You can try it your self by printing the value of *p, you will get the value of arr[0].
Let int *p be a pointer and int arr[10]
Please note that:
Arrays and Pointers are not equivalent.
sizeof operator is a compile time operator.
sizeof(arr), evaluates to 10*sizeof(int), that is 10*4=40 in your case.
When you dereference p (getting the value that p points to), it doesn't give you whole array, but one unit of
your array that is an int so, *p means arr[0]. sizeof(arr[0]) is
4 (in your case) that's obvious.
When you use sizeof(p), it will give you the size of the pointer in your machine.
In my machine it is 8.
main function's return type should be int always. It has to retport operating system the exit status of the program. If you use void it might return random garbage.
The example demonstrate the issue:
#include<stdio.h>
#include<stdlib.h>
int main(){
int *p=NULL;
int arr[10]={10,1,2,3,5,6,7,8,9,10};
p=arr;
printf("values: arr[0]=%d *p= %d\n\n",arr[0],*p);
printf("sizes : sizeof(arr[0])=%lu, sizeof(*p)= %lu sizeof(int)=%lu\n\n",sizeof(arr[0]),sizeof(*p),sizeof(int));
printf("Sizeof pointer p: %lu \n\n",sizeof(p));
printf("Sizeof arr: %lu \n\n",sizeof(arr));
printf("Pointing p to the first byte of 100 byte sequence\n\n");
p=malloc(100);
printf("Though p is pointing 100 byte block, sizeof(p)=%lu",sizeof(p));
return 0;
}
Essentially, sizeof evaluates the sizeof type but not the sizeof type it points to.
Thank you, i do appreciate your knowledge but is there any way i could
find the size of array inside another function( not the one where i
define the array).
You can't in my IMHO! You have to pass the size along with the array.
Example:
int main(){
int arr[10]={10,1,2,3,4,5};
printf("Length of array: %lu",findLength(arr,sizeof(arr)));
return 0;
}
size_t findLength(int *p,int size){
return size/sizeof(*p);
}
You have an int array and an int pointer:
int arr[10] = {1,2,3,5,6,7,8};
int* ap;
ap = arr;
In C, the expression arr is equivalent to &arr[0]. It stands to reason, then, that *ap is equivalent to arr[0], which is an int, which for your binary has a size of 4.
You also need to understand that arrays and pointers aren't the same thing. You may have been confused by the fact that arrays and pointers are often used interchangeably in the sense that a pointer can store the address of the beginning of an array (its first element, in other words) and navigate the consecutive addresses as if it had the actual array passed to it.
Whenever I want to read or write into a binary file using C, I do use the fread() and fwrite() functions. They need as a parameter the bytes of the datum that is being read or written so I use the sizeof() function. Now the question is:
The books says that I should declare a function like this:
fread(&variable,sizeof(TYPE_OF_VAR),quantity,file);
I've use the following statement which works most of the time but not always:
fread(&variable,sizeof(VARIABLE),quantity,file);
Why does it works sometimes but sometimes it doesn't?
Does it depends on the type of the variable (int, char, etc)?
Does it depends on the quantity of the datum that I use?
The thing to keep in mind is that sizeof is based on what the compiler knows about the type at compile time (ignoring VLA's for now). If you give it a variable, it will use the type of that variable.
So, the only time I can think of where it wouldn't work as you expect is with pointers.
basically what it boils down to is this:
int x[5];
int *y = &x[0];
int *p = malloc(sizeof(int) * 5);
sizeof(x); // == sizeof(int) * 5
sizeof(y); // == sizeof(int *)
sizeof(p); // == sizeof(int *)
This gets tricky when dealing with functions because arrays decay to pointers when passed to a function. Also note that all 3 of these are exactly equivalent:
int func(int *p);
int func(int p[5]);
int func(int p[]);
in all 3, p is a pointer, not an array.
See this Stack Overflow question for a discussion of heap vs. stack: What and where are the stack and heap.
sizeof() on heap elements, like pointers, will return the size of the pointer, not the number of elements that the pointer can store.
However, sizeof() on stack elements: arrays or const char * will return the length of the array or string.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LENGTH 100
int main(int argc, char *argv[])
{
char *a = NULL;
char b[10] = "abcdefghi";
printf("sizeof(b): %zu\n", sizeof(b));
a = malloc(LENGTH + 1);
if (a) {
*(a + LENGTH) = '\0';
memset(a, ' ', LENGTH);
fprintf(stdout, "a (before memcpy):\t[%s]\n", a);
printf("sizeof(a), before: %zu\n", sizeof(a));
memcpy(a, b, sizeof(b) - 1);
fprintf(stdout, "a (after memcpy):\t[%s]\n", a);
printf("sizeof(a), after: %zu\n", sizeof(a));
free(a);
}
return EXIT_SUCCESS;
}
To compile:
$ gcc -Wall sizeofTest.c -o sizeofTest
Output:
$ ./sizeofTest
sizeof(b): 10
a (before memcpy): [ ]
sizeof(a), before: 8
a (after memcpy): [abcdefghi ]
sizeof(a), after: 8
On my platform, a char * points to a memory address that takes up eight bytes.
It will always work.
int main()
{
char a[10];
int b[10];
printf("%d %d %d %d %d %d",sizeof(char),sizeof(int), sizeof(a),sizeof(b), sizeof(a[0]), sizeof(b[0]) );
}
Try the above code. You should see (depending on compiler, mine has char as 1byte and integer as 4 bytes) 1,4,10,40,1,4
It is not different for fread or fwrite or wherever you use it.
Let us assume I have declared the variable 'i' of certain datatype (might be int, char, float or double) ...
NOTE: Simply consider that 'i' is declared and dont bother if it is an int or char or float or double datatype. Since I want a generic solution I am simply mentioning that variable 'i' can be of any one of the datatypes namely int, char, float or double.
Now can I find the size of the variable 'i' without sizeof operator?
You can use the following macro, taken from here:
#define sizeof_var( var ) ((size_t)(&(var)+1)-(size_t)(&(var)))
The idea is to use pointer arithmetic ((&(var)+1)) to determine the offset of the variable, and then subtract the original address of the variable, yielding its size. For example, if you have an int16_t i variable located at 0x0002, you would be subtracting 0x0002 from 0x0006, thereby obtaining 0x4 or 4 bytes.
However, I don't really see a valid reason not to use sizeof, but I'm sure you must have one.
It's been ages since I wrote any C code and I was never good at it, but this looks about right:
int i = 1;
size_t size = (char*)(&i+1)-(char*)(&i);
printf("%zi\n", size);
I'm sure someone can tell me plenty of reasons why this is wrong, but it prints a reasonable value for me.
This works..
int main() {
int a; //try changing this to char/double/float etc each time//
char *p1, *p2;
p1 = &a;
p2 = (&a) + 1;
printf("size of variable is:%d\n", p2 - p1);
}
int *a, *b,c,d;/* one must remove the declaration of c from here*/
int c=10;
a=&c;
b=a;
a++;
d=(int)a-(int)b;
printf("size is %d",d);
I hope that below code would solve your problem in c++ without using sizeof() operator
for any variables like (int, char, float, double, char, short and many more...)
here I take integer,
int a;
then
show it as byte addressable output,
cout<<(char *)(&a + 1) - (char *)(&a);
This should work.
#define xsizeof(x) (char *)(&x+1) - (char *)&x
Try this,
#define sizeof_type( type ) ((size_t)((type*)1000 + 1 )-(size_t)((type*)1000))
For the following user-defined datatype,
struct x
{
char c;
int i;
};
sizeof_type(x) = 8
(size_t)((x*)1000 + 1 ) = 1008
(size_t)((x*)1000) = 1000
This should give you the size of your variable
#define mySizeof(type) ((uint)((type *)0+1))
Program to find Size of the variable without using sizeof operator
#include<stdio.h>
int main()
{
int *p,*q;
int no;
p=&no;
printf("Address at p=%u\n",p);
q=((&no)+1);
printf("Address at q=%u\n",q);
printf("Size of int 'no': %d Bytes\n",(int)q-(int)p);
char *cp,*cq;
char ch;
cp=&ch;
printf("\nAddress at cp=%u\n",cp);
cq=cp+1;
printf("Address at cq=%u\n",cq);
printf("Size of Char=%u Byte\n",(int)cq-(int)cp);
float *fp,*fq;
float f;
fp=&f;
printf("\nAddress at fp=%u\n",fp);
fq=fp+1;
printf("Address at fq=%u\n",fq);
printf("Size of Float=%u Bytes\n",(int)fq-(int)fp);
return 0;
}
#define GET_SIZE(myvar) ((char)( ((char*)(&myvar+1) )- ((char*)&myvar) ))
#include<stdio.h>
#include<conio.h>
struct size1
{
int a;
char b;
float c;
};
void main()
{
struct size1 *sptr=0; //declared one pointer to struct and initialise it to zero//
sptr++;
printf("size:%d\n",*sptr);
getch();
}
Below statement will give generic solution:
printf("%li\n", (void *)(&i + 1) - (void *)(&i));
i is a variable name, which can be any data type (char, short, int, float, double, struct).