sizeof operator and multidimensional table - c++

I've got a problem because i dont know how sizeof operator works. Could anyone tell me why it gives me 4 in below code?
int tab[2] = {1, 5};
int *filePathTab[1] = {NULL};
filePathTab[0] = tab;
cout << sizeof(filePathTab[0]);

filePathTab[0] has a int * as its element. The sizeof an int * on your machine is 4 bytes. If you want to know the sizeof what the int * is pointing to, an int, you have to dereference the pointer:
cout << sizeof(*filePathTab[0]);
It may turn out that the sizeof an int on your machine is also 4 bytes.

Because filePathTab[0] is of type int* (filePathTab is an array of pointers, you are considering the zeroth element) and the size of a pointer to int on your machine happens to be 4 bytes.

Sizeof gives you the size of the argument in bytes. Since pointers to int are 4 bytes long (this depends on the system), the output of sizeof is 4.

Related

Pointers to 2D arrays C, C++

I'm learning about pointers:
int x[10];
int *p = &x
this would make a pointer type int to the first element. So, if I had 2D array, I need to use double pointer: first pointer would point to the second dimension of the array. This means :
int x[3][4] = {{1,2,3,4},{5,6,7,8},{9,9,9,9}};
and when I want to point to it I must declare the size of the second dimension like this, right ?
int *p[4] = x;
or there is another way by typing : int **p; ?
and int *p[4] is array of integer pointers which takes 4 * (sizeof(int*)), right?
this would make a pointer type (int) to first element ..
No.
&x is the address of array x and is of type int (*)[10] and you can't assign it to a int * type. Both are incompatible types.
So, if I had 2D array, I need to use double pointer: first pointer would point to the second dimension of the array.
No.
In expressions, arrays converted to pointer to its first elements except when an operand of sizeof and unary & operator. Therefore, in this case the type of x will be int (*)[4] after conversion. You need a pointer to an array of 4 int instead of an array of 4 pointers
int (*p)[4] = x;
To add, the first example is not correct.
x is an array of 10 ints. p is a pointer to int and not a pointer to an array of 10 ints. When assigned to p, x decays to the type pointer to int.
The assignment should be simply:
int* p = x;
Example program:
#include <stdio.h>
main(int argc, char* argv[])
{
int x[3][4] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 987, 9, 9 } };
int(*p)[4] = x; printf("p[2][1] %d", p[2][1]);
printf("\nsizeof(p) is : %d \nsizeof(*p) is : %d\n", sizeof(p), sizeof(*p));
}
Output
p[2][1] 987
sizeof(p) is : 4
sizeof(*p) is : 16
In my system (as in yours) int and pointers are 32 bits. So the size of a pointer is 4 and the size of an int is 4 too.
p is a pointer first of all. Not an array. A pointer. It's size is 4 no less no more. That's the answer to your question
Now, just to add some useful information:
p is a pointer to an array of 4 integers. The size of what p points to is 4*4==16. (Try to change int to short in the example program, you'll have sizeof(*p) is : 8)
I can assign p=x because the type is correct, now p contains the address of x and p[0] is the same as x[0] (the same array of 4 int). p[2][3] is the same as x[2][3] and *(p[2]+3). p[2] points to the element 2 of x and p[2]+3 points to the element 3 of x[2]. (all indexing is 0 based)
// Here is not complicated matrix of size
int p[2][4]={
{1,2,3,4},
{5,6,7,8}
};
// points to the first Elements :: ptr
int (*ptr)[0] = &p;
// Now have the same adresse ( ptr and p )
printf("Hello world! %d \n",ptr[1][3]); // show 4

Why does this yield different values on using sizeof operator? [duplicate]

This question already has answers here:
Why isn't the size of an array parameter the same as within main?
(13 answers)
Closed 7 years ago.
#include <iostream>
using namespace std;
int main (void)
{
int * p = new int(40); // here `p` points to an array having space for 40 ints or space allocated is 40 bytes?
for (int i = 0; i < 2; i++)
cin>>p[i];
cout<<sizeof(p)<<"\n"; // here, the output should be size of array since p points to an array
int arr[5] = {1,2,3,4,5}; // since, here it will output 20 (space allocated for the entire array)
cout<<sizeof(arr)<<"\n";
return 0;
}
So, I have two questions (the first two comments in the program)
Here p points to an array having space for 40 ints or space allocated is 40 bytes?
Here, the output should be size of array since p points to an array because technically speaking, arr is also a pointer and when we do *arr it references to the first element of the array.
In your code, p is defined as a pointer, so sizeof(p) is the same as sizeof(int*), with is 4 on 32bit systems and 8 on 64bit systems.
In the second case, arr is a static array, so sizeof(arr) is the same as sizeof(int[5]) which returns 5*sizeof(int), assuming there's no padding or other complex work happening "under the hood".
Note that when you pass an array name as an argument to a function which accepts a pointer as a formal function parameter, the array "decays" to a pointer, so calling sizeof on an argument yields behavior you likely did not expect. For example:
Code Listing
#include <stdio.h>
void printSize(int* arg);
int main(void)
{
int *p;
int arr[10];
printf("sizeof p:%d\n", sizeof(p));
printf("sizeof arr:%d\n", sizeof(arr));
printSize(p);
printSize(arr);
return 0;
}
void printSize(int* arg)
{
printf("sizeof arg:%d\n", sizeof(arg));
}
Sample Output
sizeof p:8
sizeof arr:40
sizeof arg:8
sizeof arg:8
When you say int *p = new int(40); you are actually allocating space for a single integer and filling that space with the integer 40. If you want an array of 40 integers, you should use square brackets:
int *p = new int[40];
So, to answer question #1: neither. The space allocated is the size of one int on your system.
To answer question #2: the first line of output is the size of a single pointer on your system (because p is just a pointer). This will probably be the same as the size of an int, which is likely 4 bytes. The second line of output will be the total allocation size of your array of integers, so it will be 40*sizeof(int), or 160.
Your two uses of sizeof are querying the size of the types int* and int[5] respectively.
(also, you have a bug and meant new int[40], not new int(40), but that doesn't affect the results of sizeof)

Finding the size of int [] array

In the following function, how can we find the length of the array
int fnLenghthOfArray(int arry[]){
return sizeof(arry)/sizeof(int); // This always returns 1
}
Here this function always returns 1.
Where as, sizeof(arry)/sizeof(int) gives the actual length of the array, in the function where it is declared.
If we use vector or template like
template<typename T,int N>
int fnLenghthOfArray(T (&arry)[N]){
}
we can get the size. But here I am not allowed to change the function prototype.
Please help me to find this.
Remember, in C when you pass an array as an argument to a function, you're passing a pointer to the array. If you want to pass the size of the array, you should pass it as a separated argument.
The size of a pointer and an int is 4 or 8 or something else - depending on ABI.
In your case, it's 4, so you're getting sizeof(int *)/sizeof int which is 1.
Here is a useful trick
You can store the length of the array in the first element of it:
int myArray[]= {-1, 1, 2, 3, 4, 5};
myArray[0] = sizeof(myArray) / sizeof(myArray[0]) - 1;
//The -1 because.. the first element is only to indicate the size
Now, myArray[0] will contain the size of the array.
In function decalration, array is a pointer:
int fnLenghthOfArray(int arry[])
^
is same as int* array
And in your system sizeof(int*) == sizeof(int).
You function declaration
int fnLenghthOfArray(int arry[]);
is equivalent to
int fnLenghthOfArray(int* arry);
hence your calculation yields 1 (based on the assumption that the size of a pointer to int and size of an int are the same).
Your only option to get the size of the array is to provide an additional parameter
int fnLenghthOfArray(int arry[], std::size_t size);
Alternatively you could use one of the C++ containers like vector or array
int arry[]
is equivalent to
int *arry
and the sizeof() operator returns 4 when applied to arry because it's the size of a pointer (or reference in the case of arry[]), the size of the int is also 4 bytes and that's why it always returns 1.
To solve your problem you must implement the array in a different way. Maybe the first element should always have the size of the array. Otherwise you could use the vector class from STL or list.
int fnLenghthOfArray(int arry[]){
return sizeof(arry)/sizeof(int); // This always returns 1
}
This function returns 1 because is performing a division between the size of a pointer and the size of an integer. In most architectures, the size of a pointer is equal to the size of an integer. For instance, in the x86 architecture both have size 4 bytes.
Where as, sizeof(arry)/sizeof(int) gives the actual length of the
array, in the function where it is declared
Because in this case the compiler knows that arry is an array and its size. Whereas, in the previous function, the compiler knows arry only as a pointer. In fact, when you specify the function prototype, there is not difference between int arry[] and int * arry.
You can't get size of array in C or C++.
Array in this languages is simply pointer to first element. You need to keep size of array by yourself.
Here is code snippet using Maroun's trick.
#include<stdio.h>
void print_array(int *array);
void shift_array_normal(int *array,int arrayLen);
int main(void)
{
int array[]= {-1,32,44,185,28,256,22,50};
array[0] = sizeof(array) / sizeof(array[0]) - 1;
print_array(array);
return 0;
}
void print_array(int *array){
int index,arrayLen = array[0];
//length of array is stored in arrayLen now we can convert array back.
printf("Length of array is : %d\n",arrayLen);
//convert array back to normal.
shift_array_normal(array,arrayLen);
//print int array .
for(index = 0; index < arrayLen; index++)
printf("array[%d] = %d\n",index,array[index]);
}
/*removing length element from array and converting it back to normal array*/
void shift_array_normal(int *array,int arrayLen){
int index;
for(index = 0; index < arrayLen; index++)
array[index] = array[index + 1];
}
#include<iostream>
int main()
{
int array[300];
int d = sizeof(array)/4;
std::cout<<d;
}
Use:
// sizeof(array)/4 for "int" array reserves 4 bits.
// sizeof(array)/4 for "float" array reserves 4 bits.
// sizeof(array) for "char" array reserves 2 bits.
// sizeof(array) for "bool" array reserves 2 bits.
// sizeof(array)/8 for "double" array reserves 8 bits.
// sizeof(array)/16 for "long double" array reserves 16 bits.

c++ sizeof(array) return twice the array's declared length

I have a section of code in which two array are declared with sizes of 6 and 13, but when 'sizeof()' is used the lengths are returned as 12 and 26.
#include <iostream>
using namespace std;
int main(){
enum charRaces {DWARF,ELF,GNOME,HALFELF,HALFLING,HUMAN};
enum classes{WARRIOR,FIGHTER,RANGER,PALADIN,WIZARD,MAGE,ILLUSIONIST,PRIEST,CLERIC,DRUID,ROGUE,THEIF,BARD};
short int races[6] = {DWARF,ELF,GNOME,HALFELF,HALFLING,HUMAN};
short int classes[13] = {WARRIOR,FIGHTER,RANGER,PALADIN,WIZARD,MAGE,ILLUSIONIST,PRIEST,CLERIC,DRUID,ROGUE,THEIF,BARD};
cout << "sizeof(races)\t" << sizeof(races) << endl;
cout << "sizeof(classes)\t" << sizeof(classes) << endl;
system("pause");
return(0);
}
sizeof returns the size of a variable (in this case, your arrays), where sizeof(char) is 1. Since a char is one byte wide, sizeof returns the size of the variable in bytes. Since each short int is two bytes wide on your system, an array of 6 of them will have size 12, and an array of 13 will have size 26.
sizeof returns the size in bytes, which for an array is the number of items × the size of each item. To get the number of items divide by the size of one element.
sizeof(races) / sizeof(races[0])
Be careful with this. It will only work for arrays whose size is known at compile time. This will not work:
void func(short int array[])
{
// DOES NOT WORK
size_t size = sizeof(array) / sizeof(array[0]);
}
Here array is actually a short int * and sizeof(array) does not return the actual size of the array, which is unknown at compile time.
This is one of many reasons to prefer std::vector or std::array to raw arrays in C++.
sizeof returns the actual memory in bytes used by the array. A fairly common idiom is to do something like this:
short int races[6] = {DWARF,ELF,GNOME,HALFELF,HALFLING,HUMAN};
size_t num_races = sizeof(races) / sizeof(races[0]);
num_races would then have the number of elements in the array stored in it.
sizeof is an operator in C++ that measure the size in number of bytes.I think in your machine integer take 2 bytes that's why It's displaying the double the size of the array.
The sizeof operator is measured in units such that an unsigned char is 1 unit.
On your platform, short is twice as large as char, thus the results you're seeing.
To properly determine array length, you could use a macro such as:
#define ARRAY_LEN(ary) (sizeof (ary) / sizeof (ary[0]))
The sizeof operator returns the size in bytes required to represent the type (at compile time).
double array[10]; // type of array is: double[10]
sizeof(array) has the same meaning as sizeof(double[10]), which is equal to:
sizeof(double) * 10
It's an array that can hold 10 double values. sizeof(array[0]) means: size of a single element in array, which is the same as sizeof(double) here. To get the actual number of elements, you have to divide the size of the array by the size of a single element:
size_t num_elem = sizeof(array) / sizeof(array[0]);
However, this doesn't work on pointers!
double* p = array;
sizeof(p) actually translates to sizeof(double*). Its size has nothing to do with the size of double or the size of the array it's pointing to.
Instead, it's the size required to store the address to a memory location (32 bits on a 32bit operating). The information about the number of elements is lost!
If you want to safely get the number of elements in an array, you can use this template:
template<typename T, size_t N>
size_t inline static_arrlen(T (&)[N]) {
return N;
}
At compile-time, it deduces the type T and number of elements N, returning N.
size_t num_elem = static_arrlen(array); // T=double, N=10
If you're trying to get the array size from a pointer, it won't compile:
static_arrlen(p); // ERROR: could not deduce template argument
// for 'T (&)[N]' from 'double *'

A doubt about sizeof

I was trying to do something using sizeof operator in c++.
Please refer to the following code snippet.
http://ideone.com//HgGYB
#include <iostream>
using namespace std;
int main()
{
int *pint = new int[5];
int temp = sizeof(*pint);
cout << "Size of the int array is " << temp << endl;
return 0;
}
I was expecting the output as 5*4 = 20. Surprisingly it comes to 4. Any ideas ?
Here is pint is an int*. So,
sizeof(*pint) == sizeof(int)
Compiler doesn't know about new int[5], when it does sizeof(*pint) (because sizeof() is a compile time operator).
[Note: Try the same test with statically declared array, int pint[5]; and will see the expected result.
Additionally, sizeof() returns size_t (which is an unsigned value), so it should be:
size_t temp = sizeof(...);
]
Dynamically sized arrays lose their size information- the size is only the size of one integer, as pint is a pointer to int, and *pint is an integer, not an array type of any size.
There is no way for C++ to know the size of the array.
In your case,
*pint
returns an int, and sizeof(int) is 4 on your machine.
All fine. You ask for the size of an int which will be 4 bytes.
pint is a pointer to int that just happens to point to the beginning of an array. It contains no information about this array.
It is giving you the size of what the pointer points to - the first location in the array.
In the current case sizeof(*pint) is giving the sizeof(int), so its returning 4 . But, even if you will try sizeof(pint), it will return you the size of a pointer. Which will most probably be 4 if yours is a 32 bit machine else it will be 8, if 64 bit machine.
Now you have asked, why it is not returning 4*5 = 20. Since pint points to an integer array. Yes, pint points to an integer array, but its not an array. The difference is :
Array have a fixed size. you can redectare it at all. While pointers can point to any object of any size.
Since sizeof operator is evaluated at compile time, so compiler dont have any way to know at which size of array this pointer is pointing and so cant tell the size of that object and so it always return only the size of pointer. now you can understand, why in case of pointers compiler gives size of the pointer (ie space occupied by pointer in memory), but in case of array it gives full size.