Inserting a sub-array into a vector - c++

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.

Related

How unique() function for array works

int a[4] = {3,1,2,3};
sort(a,a+n);
int j = unique(a,a+n) - a; // j=3
In this code variable j returns total numbers of unique element in the array a. But I couldn't understand how this code is working.
I know that in lists,
list::unique() is an inbuilt function in C++ STL which removes all duplicate consecutive elements from the list. It works only on sorted lists.
std::unique() is going to move the duplicates in the range [a+0, a+n), and it returns a new iterator in that range that will mark the new "end" of the array, i.e, where the first non-unique item is now moved to in the array.
If you then subtract from that iterator the beginning iterator, which you do with unique(a,a+n) - a;, you get the number of elements that are between the start of the array and the new "end". This is how you are able to get the count of the unique elements.
It should be noted that I use "end" here because arrays have a fixed size. You aren't actually changing the size of the array at all, you are just moving the duplicate elements to the back of the array, and keeping the unique elements at the front.
It should also be noted that after this happens, everything at and after the iterator returned by unique() will have an unspecified value. It is legal to set new values to them, but using an unspecified value leads to undefined behavior.

H­ow d­oes List::in­sert w­ork with a­rr­a­ys­

I am on youtube looking over tutorials. One had a block of code using the list library as such:
int arr1[5]{ 1,2,3,4,5 };
list<int> list1;
list1.insert(list1.begin(), arr1, arr1 + 5);
My question is, how can one use an array like this? Last I checked, arr1 is an array not a pointer that you use to loop through elements. How does the insert function work?
When an array is used by name, it's name references to first element of the array. For an array arr whenever you say arr[x], [] is defined in terms of pointers. It means start at a pointer referencing arr and move x steps ahead. A size of each step is the sizeof datatype your array is made up of. Thus,arr[x] can also be written as *(arr + x), dereferencing the pointer after x steps.
Now speaking of your list insertion, it means copy all the elements between pointers arr and arr + 5 to the list.
arr1 can be used as a pointer to the beginning of the array, because it gets converted automatically.

Calculate number of elements in an array based on pointers to the first and last elements

Suppose there exists an array, A, such that its elements are of struct Element and I am told that the struct Element is packed with no padding.
If I am given pointers to the first and last element in A, can I determine the number of elements in A based on the address of the pointers and amount of memory an Element takes up? Or does the structure of an array in memory not work like that.
My thought is if the pointers I'm given are Element* start and Element* finish...
number of elements = (finish - start) / sizeof(Element)
Is this logical thinking?
If you have:
Element* start; // first element
Element* finish; // last element
Then:
numElements = finish - start + 1;
If finish is like an end in STL, you do not have the +1.
Because of pointer arithmetic, you do not have to divide by sizeof(Element)
With regard to considering whether there might be padding at the structure end, as Billy indicated, sizeof already contains that, as will pointer arithmetic. from the C++14 final draft:
N3797/5.3.3/2 [ sizeof ]
When applied to a class, the result is the number of bytes in an
object of that class including any padding required for placing objects of that type in an array.
When you use pointer arithmetic, you can say that the "unit" is the size of one element of the type pointed to.
I.e. if you have Element* start pointing to the 0-th element of an array, start + 1 will point to the 1-st element of that array.
So, when you use finish - start, you already get the number of elements between them, and there is no need to divide by sizeof(Element).

erasing an element from a string vector

In my program I have created a vector of string type (vector<string> names;).
After putting some values in it, I came in the situation where I wish to erase an element from it. I know that I can do this by typing: names.erase(<pointer to the element to be erased>);
However the only thing i know is that I wish to erase the element i (i is a counter in a loop). The starting position (pointer) of the i'th position is uknown, because the vector is a string (i.e. If it was an int vector I could do:
names.erase(names.begin()+i*sizeof(int))
Would someone please explain how I can find the position in memory of the i'th element, or generally how I can erase the i'th element without knowing its position.
It doesn't matter about the size of the elements. names.begin() + i gives you an iterator to the ith element of the vector. You don't move an iterator along in byte steps - you move it along an element at a time.
You definitely should not be doing names.begin() + i * sizeof(int) if you have a vector of ints. And even if it were the case that you had to add the size in bytes like this, the size of a std::string object is always fixed, regardless of the length of the string. That is sizeof(std::string) is a constant value. In fact, the size of any type is fixed in C++.
You definitely should use iterators to manipulate vector.
The simplest way to locate i'th element is:
std::vector<string>::iterator l_it(names.begin());
l_it += i;
Also be careful with erasing, because std::vector::erase relocates the rest of array (and moves indexes).
http://www.cplusplus.com/reference/vector/vector/erase/
need to use iterator as below
vector<string>::iterator lIter = lStrVec.begin();
lIter = (lIter + (i-1));
lStrVec.erase(lIter);
Note that if yu need to erase i th element move forward the iterator by i-1

How can i find a particular index in a heap in c++?

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.