strange behaviour using sizeof in C++ [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)
When a function has a specific-size array parameter, why is it replaced with a pointer?
(3 answers)
Closed 4 years ago.
I'm very new to C++. From examples, I find this use of sizeof in order to retrieve the length of an array
int main()
{
int newdens[10];
// the first line returns 10 which is correct
std::cout << "\nLength of array = " << (sizeof(v1)/sizeof(*v1)) << std::endl;
std::cout << "\nLength of array = " << (sizeof(v1) << std::endl; //returns 40
std::cout << "\nLength of array = " << (sizeof(*v1)) << std::endl; //returns 4
}
But if i wrote a function like this
#include <iostream>
void myCounter(int v1[])
{
int L, L2, L3;
L = (sizeof(v1)/sizeof(*v1));
L2 = (sizeof(v1));
L3 = (sizeof(*v1));
std::cout << "\nLength of array = " << L << std::endl;
std::cout << "\nLength of array = " << L2 << std::endl;
std::cout << "\nLength of array = " << L3 << std::endl;
}
int main()
{
int v1[10];
std::cout << "\nLength of array = " << (sizeof(v1)/sizeof(*v1)) << std::endl;
std::cout << "\nLength of array = " << (sizeof(v1)) << std::endl;
std::cout << "\nLength of array = " << (sizeof(*v1)) << std::endl;
myCounter(v1);
}
the outputs are L=2, L2 = 8, L3 = 4. I can't understand where the problem is.
How to retrieve the correct lenght of v1 inside the function?

Your problem here is that sizeof() is resolved at compile time. As it has no information about how large is your array, it cannot tell its size. It interprets it as a pointer to an int, which is 64-bit on your machine.
The best way for you is to use std::vector instead of C-style array and use its method size().

Related

Unexpected result for "&array" [duplicate]

This question already has answers here:
Why are `&array` and `array` pointing to the same address?
(2 answers)
How come an array's address is equal to its value in C?
(6 answers)
Closed 1 year ago.
I am confused about array usage as pointer and result of that. Let me explain. When I try this
#include <iostream>
using namespace std;
int main()
{
int a = 10;
int *myPointer = &a;
cout << "*myPointer: \t" << *myPointer << endl;
cout << "myPointer: \t" << myPointer << endl;
cout << "&myPointer: \t" << &myPointer << endl;
cout << "myPointer[0]: \t" << myPointer[0] << endl;
cout << endl;
int myArray[3] = {1,2,3};
cout << "*myArray: \t" << *myArray << endl;
cout << "myArray: \t" << myArray << endl;
cout << "&myArray: \t" << &myArray << endl;
return 0;
}
All of output are exactly what I expected, except last one (&myArray). Lets say my ram something like this:
Address
Variable
Value
0xA100
a
10
0xA101
myPtr
0xA100
0xA102
1
0xA103
2
0xA104
3
0xA105
myArray
0xA102
If I imagine it correctly, then how "&myArray" can be same with "myArray"? Actually, I think it can be anything but 0xA102. Because, this result means that "myArray" is in 0xA102 and value of pointed by myArray is in 0xA102 too. And I know it is weird but it means also, as a value "1", is in 0xA102 too. (At least I got it from this result).
So, I cannot catch the point. I think the result has to be 0xA105 if "&" means address. If yes, why result is not 0xA105. If not, why they have different usage although arrays are pointers.
Is there anybody can clarify the matter?
Thanks.

passing an 2d array pointer to a function in c++ [duplicate]

This question already has answers here:
Passing a 2D array to a C++ function
(18 answers)
Closed 4 years ago.
I know how to pass 1D array pointer to a function by the following code
void fiddleWithArray(int*);
int main(){
int list[10] = {1, 3, 5, 7, 9, 11, 13, 17};
cout << "List at 0 before being passed is... " << list[0][0] << endl;
cout << "List at 1 before being passed is... " << list[1][0] << endl;
fiddleWithArray(list);
cout << "List at 0 after being passed is... " << list[0][0] << endl;
cout << "List at 1 after being passed is... " << list[1][0] << endl;
}
void fiddleWithArray(int* input){
input[0] = 45;
input[1] = 18;
}
However, when I try to do something similar for a 2D array(as shown below) I get an error.
void fiddleWithArray (int** input);
int main ()
{
int list [10][2]={{1,3},{5,7},{9,11},{13,17},{7,4},{5,90},{9,1},{3,25}};
int ** pointer;
pointer=&list;
cout<< "List at 0 before being passed is ... "<< list[0][0]<< endl;
cout<< "List at 1 before being passed is ... "<< list[1][0]<< endl;
fiddleWithArray(pointer);
cout<< "List at 0 after being passed is ... "<< list[0][0]<< endl;
cout<< "List at 1 after being passed is ... "<< list[1][0]<< endl;
}
void fiddleWithArray(int** input)
{
cout << input [6][1]<< endl;
}
The compiler gives an error saying "error: cannot convert ‘int (*)[10][2]’ to ‘int**’ in assignment
pointer=&list;"
I am also open to alternate methods of passing a 2D array pointer to a function.
Keeping your data structure, if you want to pass list to fiddleWithArray you can declare it as
void fiddleWithArray (int input[][2]);
and then, in the main program, call it as
fiddleWithArray(list);
There is also another problem in your program: cout << list[0] does not work. If you want to print the contents of the array when the first index is fixed to 0 you would write something like
cout << list[0][0] << " " << list[0][1]
If you instead intended to write the array where the second index is fixed to 0 or 1, then, to keep things easily, you need a short loop like
for (unsigned int i = 0; i < 10; i++)
cout << list[i][0] << " ";
cout << endl;
Finally, instead of using int[][] you may want to use std::arrayintroduced in C++11.
void fiddleWithArray(int input[10][2])
{
cout << input[6][1] << endl;
}
int main()
{
int list[10][2] = {{1,3},{5,7},{9,11},{13,17},{7,4},{5,90},{9,1},{3,25}};
int (*pointer)[10][2];
pointer=&list;
cout << "List at 0 before being passed is ... "<< list[0][0]<< endl;
cout << "List at 1 before being passed is ... "<< list[1][0]<< endl;
fiddleWithArray(*pointer);
cout << "List at 0 after being passed is ... "<< list[0][0]<< endl;
cout << "List at 1 after being passed is ... "<< list[1][0]<< endl;
}
Will be better using std::array

Display All vectors inside of a RECT array C++

This is my third question on this topic, Instead of asking a new question in the comments I thought it would be better to start a new thread.
The full code can be found here:
C++ CvSeq Accessing arrays that are stored
And using the following code I can display the most recent vector that has been added to the RECT array(Note that this is placed inside of the for loop):
RECT& lastRect = detectBox->back();
std::cout << "Left: " << lastRect.left << std::endl;
std::cout << "Right: " << lastRect.right << std::endl;
std::cout << "Top: " << lastRect.top << std::endl;
std::cout << "Bottom: " << lastRect.bottom << std::endl;
What I am now trying to do is create a loop outside of this for loop that will display all of the vectors present in detectBox. I havent been able to determine how many vectors are actually present in the array, and therefore cannot loop through the vectors.
I tried using the following:
int i = 0;
while ((*detectBox)[i].left!=NULL)
{
std::cout << "Left: " << (*detectBox)[i].left << std::endl;
std::cout << "Right: " << (*detectBox)[i].right << std::endl;
std::cout << "Top: " << (*detectBox)[i].top << std::endl;
std::cout << "Bottom: " << (*detectBox)[i].bottom << std::endl;
i++;
}
And have also tried playing around with sizeof(*detectBox) , but only have an answer of 32 being returned...
Okay, you are using the wrong terms here. The variable detectBox is a vector (or rather a pointer to a vector it seems). There are three ways to iterate over it (I'll show them a little later). It is not an array, it is not an array of vectors. It is a pointer to a vector of RECT structures.
Now as for how to iterate over the vector. It is like you iterate over any vector.
The first way is to use the C way, by using indexes:
for (unsigned i = 0; i < detectBox->size(); ++i)
{
RECT rect = detectBox->at(i);
std::cout << "Left: " << rect.left << std::endl;
...
}
The second way is the traditional C++ way using iterators:
for (std::vector<RECT>::iterator i = detectBox->begin();
i != detectBox->end();
++i)
{
std::cout << "Left: " << i->left << std::endl;
...
}
The last way is to use range for loops introduced in the C++11 standard:
for (RECT const& rect : *detectBox)
{
std::cout << "Left: " << rect.left << std::endl;
...
}
The propblem with your attempt of the loop, with the condition (*detectBox)[i].left!=NULL is that the member variable left is not a pointer and that when you go out of bounds you are not guaranteed to have a "NULL" value (instead it will be indeterminate and will seem random).

Memory location for a pointer passed in a function gets deleted [duplicate]

This question already has answers here:
Pointer errors in the method of transmission(c++)
(4 answers)
Closed 8 years ago.
Question: I can't seem to set a pointer to an address that was created inside of a function. It always gets set to Null, how do I fix this?
Problem: I believe the problem is caused by the variable being created inside of another function. What's happening is that after the function executes, the pointer is set to NULL again.
Code:
void listAdd(int *list, int &length) {
int* tempList = new int[ length + 1 ];
for( int i = 0; i < length; i ++ )
{
(tempList)[ i ] = (list)[ i ];
}
cout << " Previous adress: " << hex << list << endl;
if ( list != NULL )
delete[] list;
list = new int[ length + 1 ];
cout << " New address: " << hex << list << endl << dec;
for( int i = 0; i < length; i ++ )
{
(list)[ i ] = (tempList)[ i ];
}
delete[] tempList;
cout << " Enter a number: ";
int stored = 0;
cin >> stored;
(list)[length -1] = stored;
length ++;
cout << " Length: " << length << "\n";
cout << " value at array point 0: " << (list)[length -1];
cout << "\n retry " << (list)[length-1] <<"\n";
cout << "\n \n \n This is pointing to 0x" << hex << list << '\n' << flush;
}
It seems you would like the changes to list to be valid after the function returned: since list is passed by value, the object manipulated inside the function happens to be a copy of the one you passed in. You probably either want to pass the object by reference, i.e.:
void listAdd(int*& list, int &length) {
// ...
}
... or return the result
int* listAdd(int* list, int& length) {
// ...
return list;
}
list = listAdd(list, length);
Well, realistically, you really really want to encapsulate the objects in a class or just use std::vector<int>.

Address of function pointers in C++ [duplicate]

This question already has answers here:
How to print function pointers with cout?
(7 answers)
Closed 9 years ago.
I'm not clear on what the values that are being returning from calling:
&next, fp, *fp, &return_func_ptr, fp_ptr, &fp_ptr, *fp_ptr
They all seem to give me the value 1. What does it mean?
Also, how would I declare
int (*return_f())(char)
to receive a parameter without using typedef?
#include <iostream>
int next(int n){
return n+99;
}
// returns pointer to a function
typedef int (*fptr)(int); // using typdef
fptr return_func_ptr(){
return next;
}
int f(char){
return 0;
}
int (*return_f())(char){ // how do you pass a parameter here?
// std::cout << "do something with " << param << std::endl;
return f;
}
int main()
{
int x = 5;
// p points to x
int *p = &x;
std::cout << "x=" << x << std::endl; // 5, value of x
std::cout << "&x=" << &x << std::endl; // 0x7fff6447a82c, address of x
std::cout << "p=" << p << std::endl; // 0x7fff6447a82c, value of p is address of x
std::cout << "*p=" << *p << std::endl; // 5, value of x (p dereferenced)
std::cout << "&p=" << &p << std::endl; // 0x7fff6447a820, address of p pointer
// change value of x thru p
// p = 6; // error, can't set int* to int
*p = 6;
std::cout << "x=" << x << std::endl; // 6
int y = 2;
// int *q = y; // error can't initiate with type int, needs int*
// pointer to a function
int (*fp)(int);
std::cout << "&fp=" << &fp << std::endl; // 0x7fff66da6810, address of pointer fp
std::cout << "fp=" << fp << std::endl; // 0, value of pointer fp
fp = &next; // fp points to function next(int)
fp = next;
std::cout << "&next=" << &next << std::endl; // 1, address of function?
std::cout << "fp=" << fp << std::endl; // 1, value is address of function?
std::cout << "&fp=" << &fp << std::endl; // 0x7fff66da6810, address of pointer fp?
std::cout << "*fp=" << *fp << std::endl; // 1, address of function?
// calling function thru pointer
int i = 0;
i = (*fp)(i);
std::cout << "i=" << i << std::endl; // 99
i = fp(i);
std::cout << "i=" << i << std::endl; // 198
// function returns pointer to function
fptr fp_ptr = return_func_ptr();
std::cout << "&return_func_ptr=" << &return_func_ptr << std::endl; // 1
std::cout << "fp_ptr=" << *fp_ptr << std::endl; // 1
std::cout << "&fp_ptr=" << *fp_ptr << std::endl; // 1
std::cout << "*fp_ptr=" << *fp_ptr << std::endl; // 1
int j = fp_ptr(1);
std::cout << "j=" << j << std::endl; // 100
}
There is some pointer here who seems not clear :
// pointer to a function
int (*fp)(int);
std::cout << "&fp=" << &fp << std::endl; // 0x7fff66da6810, address of pointer fp
std::cout << "fp=" << fp << std::endl; // 0, value of pointer fp
Here fp is undefined. Those lines have an undefined behaviour.
After that :
// function returns pointer to function
fptr fp_ptr = return_func_ptr();
std::cout << "&return_func_ptr=" << &return_func_ptr << std::endl; // 1
std::cout << "fp_ptr=" << *fp_ptr << std::endl; // 1
std::cout << "&fp_ptr=" << *fp_ptr << std::endl; // 1
// ^^^^^^^^^^ ^^^^^^^
std::cout << "*fp_ptr=" << *fp_ptr << std::endl; // 1
There are two things here :
On the line I pointed, I'm not sure it is what you wanted to test.
Also, cout doesn't have an overload to take a function pointer, it will take a bool instead. So it should be :
std::cout << "fn_ptr=" << reinterpret_cast<void*>( fn_ptr ) << std::endl;
I would suggest you to read this article about function pointer, it explains almost all you need to know : http://www.learncpp.com/cpp-tutorial/78-function-pointers/
std::cout << "fp_ptr=" << *fp_ptr << std::endl;
should be
std::cout << "fp_ptr=" << (void*)fp_ptr << std::endl;
The cout operator doesn't have an overload for a function pointer, so it uses bool instead. That's why you always get 1 as output. When I compile your code, I even get a warning for that, telling me that it will always evaluate to true. You should switch on all warnings and try to get rid of them.