If I have a pointer that is pointing to an element in a vector, say element 2, and then that element gets swapped with element 4 of the same vector. Is the pointer now pointing to element 2, element 4, or neither? Example:
vector a is equal to [1,2,3,4,5]
create pointer that points to the element 2, which is equal to 3 in this case
swap elements 2 and 4
vector a is now [1,2,5,4,3]
where is the vector pointing to?
You mean, "where is the pointer pointing to?". If that's the case, it'll point to the same location in memory as before which is now occupied by the value 5.
Also, by swapping I assume you meant swapping the values between two locations.
Why?
Simply because your pointer points to a memory location. What's stored there doesn't matter --- it could be a value, or it could be garbage. When you dereference it (to see what the value is) it will return the value stored at that location.
Since you've swapped the values, the value at that location is 5 not 3 hence, the pointer is still pointing to the same location and is unchanged but the value at the location has changed.
Sample Code:
// Create the vector
int a[] = {1,2,3,4,5};
int* ptr = &a[2];
// Display original status
std::cout<<"Original Value: "<<*ptr<<std::endl;
std::cout<<"Address: "<<ptr<<std::endl;
// Swap values
std::swap(a[2],a[4]);
// Check
std::cout<<"New Value: "<<*ptr<<std::endl;
std::cout<<"Address: "<<ptr<<std::endl;
Note:
I've used an array of integers in the example but if by vector you meant std::vector, the same will hold assuming no reallocation has taken place (check out this SO answer).
Related
Can I rely on the compilers behaviour in this case?
Lets assume I have a std::map...
std::map<int, int[10]> _map;
... and later on I perform...
++(_map[5][0]);
... and 5 is a new value for the map
Am I going to have 0 in the 0th element of the array before performing the incrementation?
You'd have a 1 in the 0th element of the array.
When _map[5] is called, the int array associated with 5 is created, and initialized with a default value of 0 for each element, before being returned as a reference. Then you access index 0, and increment it with ++, so the value will be set to 1.
Think of it like this:
auto& arr = _map[5];//Array created and initialized, because of behavior of std::map::operator[]
int & i = arr[0];
++i;
Which is identical code to what you wrote.
The following statement inserts part of an array into an empty vector. It then prints the last elemnt inserted which is 14 in this case. My question is, how is the final array element that is inserted being determined with this syntax? How is "myArray+3" returning the third element in the array to the function?
vector <int> myVector(10);
int myArray[5] = {3,9,14,19,94};
myVector.insert(myVector.begin(), myArray, myArray+3);
cout << myVector.at(2) << endl;
For starters the vector is not empty. It has 10 elements initialized by zeroes.
vector <int> myVector(10);
As for these arguments
myArray, myArray+3
then they specify a range in the array the following way
[&myArray[0], &myArray[3])
^^^ ^^^
That means that the elements pointed to by these pointers
&myArray[0], &myArray[1], &myArray[2]
will be included in the vector. That is the second value of the range specifies elements before the value.
The element pointed to by the pointer &myArray[3] (that is by the pointer myArray + 3) will not be inserted to the vector.
Compare for example. If an array has N elements then the range of acceptable indices for its element is
[0, N-1]
^^^ ^^^
that can be also specified like
[0, N)
^^^ ^^^
Arrays in C++ are laid out in a contiguous fashion, so that the address of the array is the same as the address of the first element of the array, followed by the address of the next, and the next, etc.
Now when you do myArray + 3, this is actually saying, "Go to the first element and get the third element from the start position".
So if you had done (myArray + 1) + 3, this will mean to first from the first position to the second, and using your new position as a reference point, move three positions from there.
How does it know where to go? Simply by taking the size in bytes of a single element of the array and multiplying that by the distance you wanted to move forward, and then adding this value to the address of the reference position, and voila! You have gotten to the nth element of the array.
I'm using a convolution process using a 3x3 grid over a 2d image that is represented in a 1d array. I am iterating over certain pixels and need access to the surrounding pixels (ignoring edge cases). Is it possible to have a pointer that always points to a location next to another pointer?
int* a = new int[5];
//populate with data (0, 2, 4, 6, 8)
int* b = &a[2]; //4
int* c = b+1; //6
b++; //b->6, c->6
//What if after b++ I want c->8?
Is there any way to make a pointer relative to another pointer such that when the main pointer is changed, the other pointers change with it? So, a pointer that always points to the neighbor of another pointer.
Incrementing b does not change c. If you want both pointers to move in parallel, you must increment both of them:
b++;
c++;
This seems like more trouble than it's worth, though, since you can just do b + 1 to find the "next" element in the array.
I have a vector array a = {1,12,12,6,5}. If i create a max heap than it will return me 12 as a first element. How do i know that the returned 12 is the 2nd or 3rd element of array a? I need the index of the returned element. Thanks.
Create a std::pair<int, int> array, where first element is an actual value and second is an index in initial array. Then, create a heap on this array and get the element index of the top element with maxHeapElement.second.
But remember, that it will always show you the right-most element of the same value since std::pair is compared lexicographical.
Consider the following code
int tab2[2];
tab2[0]=5;
tab2[1]=3;
std::cout << tab2[1] << std::endl;
std::cout << (&tab2)[1] << std::endl;
As I have read in other topics, an array can decay to pointer at its first element. Then why doesn't the [] doesn't work the same for tab2 and &tab2 in the above code? What is different?
It's already "converted" as a pointer. You can use the [] notation with arrays or pointers...
(&tab2) means you get the address of your array... In a pointer perspective, it's a pointer to a pointer ( ** ).
So you are trying to convert a variable (which is an array) as a pointer. Ok, but then you try to access the [1] element, which of course does not exist, as your pointer points to your array's address... Such a notation would expect a second array.
This expression:
(&tab2)[1]
Gets you a pointer to an array of 2 ints. Then uses array syntax on that pointer-to-an-array to get you the 1st 2 element int array after tab2.
So you have in memory
tab2
0 1 // index into tab2
5 3 // values
You get a pointer to the array
0 1
&tab2 -> 5 3
Then you go 1 array of 2 ints past tab2
0 1 2 3
&tab2 -> 5 3 ? ?
/|\
(&tab2)[1]
When you use (&tab2), you are retrieving the address of your array. Your statement itself answers your question.
Had you used (*(&tab2)), you would have got what you were expecting as output - 3.
What you've done by adding address-of (&) to tab2 is given yourself the memory address of the tab2 pointer, or a pointer to a pointer (int**). So logically, yes, indexing it makes sense. However, &tab2 is not the same as tab2. &tab2 points to the pointer itsefl, while tab2 points to the array. By indexing &tab2 with 1, you've told it to look at the next element in sequence, which doesn't exist (or it does exist, but belongs to another variable). Had you indexed it with 0, this would have been fine as you would be looking at the "root" of the memory sequence.
Indexing just tab2 is fine as well obviously, because it points to an array.