std::swap returns 0xBAADF00D - c++

I'm trying to swap two std::list< dontcare* >::iterators under Visual 2005.
Iter it1 = ... ,it2 = ...; // it1 and it2 are ok, not end() or such
if(...){
std::swap(it1,it2);
}
The swap works, but when I leave the if() scope, it1 points to 0xbaadfood. It2 is ok though.I tried several variations, including swap_iter and a hand-made swap.
Any help appreciated :)
EDIT
Ok, so shame time.
The swapped it1 was a local variable in the if's scope.
F**king cut'n pasting. Sorry for wasting your time :/

This following program
#include <iostream>
#include <vector>
#include <algorithm>
int main(){
std::vector<int> v;
for(std::vector<int>::size_type idx=0; idx<10; ++idx)
v.push_back(static_cast<int>(idx));
std::vector<int>::iterator it1 = v.begin();
std::vector<int>::iterator it2 = v.begin() + v.size()/2;
std::cout << static_cast<void*>(&*it1) << ':' << *it1
<< ' ' << static_cast<void*>(&*it2) << ':' << *it2 << '\n';
std::swap(it1,it2);
std::cout << static_cast<void*>(&*it1) << ':' << *it1
<< ' ' << static_cast<void*>(&*it2) << ':' << *it2 << '\n';
return 0;
}
compiles, runs, and, as expected, prints
00032A28:0 00032A3C:5
00032A3C:5 00032A28:0
for me.
If it does something else for you, either your compiler or your standard library is broken.
If it does the same for you, then the error is somewhere in the difference between your code and my code. Where, we can't know, because we don't know your code.

Are you omitting code inside your if? Most likely something else within your if check, but after the swap is actually invalidating the iterator (perhaps an erase).

A WAG but perhaps swap is constructing new objects and copying them (and the copy is not valid because it uses the default constructor)?

Related

C++ First two elements not printing properly when using iterator

I have looked for this and found something here: Variable not printing on iteration but I'm not sure if that necessarily applies.
What I have going on is my program correctly prints all values when I call it like this:
for (int i = 0; i < SampleVec.Matchups().size(); ++i){
std::cout << SampleVec.Matchups()[i] << std::endl;
}
or when I call it like this:
std::vector<int> temp;
temp = SampleVec.Matchups();
for (std::vector<int>::const_iterator iter = temp.begin(); iter != temp.end(); iter++){
std::cout << *iter << std::endl;
}
but when I write it like this
for (std::vector<int>::const_iterator iter = SampleVec.Matchups().begin(); iter != SampleVec.Matchups().end(); iter++){
std::cout << *iter << std::endl;
}
the first two values show up as a 0 and the rest print correctly. In the link I posted they talk about stripping newlines from the input, but I don't know if that applies here or even how to do that. I can post full code if needed to run and see the functionality in action.
for (std::vector<int>::const_iterator iter = SampleVec.Matchups().begin(); iter != SampleVec.Matchups().end(); iter++){
std::cout << *iter << std::endl;
}
begin() returns the iterator of the beginning of a temporary std::vector returned by Matchups(). At the moment of using iter it's a dangling iterator because the temporary has been destroyed and thus you have Undefined Behaviour.
You have to store the result before trying to access it through an iterator like you do in example 2.

C++ How to print a string backwards?

I'm trying to print an std::string backwards with iterators like this:
std::string back = "hello";
for(std::string::iterator it=back.end(); it!=back.begin(); --it)
{
std::cout << (*it);
}
But the output will only print out:
olle
Why is it not also printing out the h? I tried a couple of different things and played around with it, but I just can't seem to figure out why. Any help would be greatly appreciated, thanks!! :)
std::string back = "hello";
for (std::string::reverse_iterator it = back.rbegin(); it != back.rend(); ++it)
{
std::cout << (*it);
}
std::string::iterator it=back.end();
it gets initialized to end(). Then, inside of the loop:
std::cout << (*it);
Since the initial value of it is end(), dereferencing it is undefined behavior, with unpredictable results.
The correct approach is to decrement it before it gets dereferenced:
for(std::string::iterator it=back.end(); it!=back.begin(); )
{
--it;
std::cout << (*it);
}
If you don't want a for-loop:
#include <algorithm>
std::string string_back = "hello";
std::reverse(string_back.begin(), string_back.end());
std::cout << string_back; // prints 'olleh'

remove duplicates entry in vectors

I am trying to add objects using class(Sample),sort my vector and after that remove duplicates entries in my vector.
my codes (this is just part of my codes in my program)
vector<Sample> sampleVector;
sort(sampleVector.begin(), sampleVector.end());
sampleVector.erase(std::unique(sampleVector.begin(),sampleVector.end(),sampleVector.end()));
but however it when I tried to run my program it shows this error.
Type 'std::__1::__wrap_iter<Sample *>' does not provide a call operator
and I realized that most likely the error is caused by this line
sampleVector.erase(std::unique(sampleVector.begin(),sampleVector.end(),sampleVector.end()));
What should I do so that I can make it work to remove duplicate entries in my vector?
thanks in advance
Another thing I have tried but it's not working.
bool myfunction (Sample *i,Sample *j) {
return (i==j);
}
std::vector<Sample>::iterator it;
vector<Sample> sampleVector;
it = std::unique(sampleVector.begin(), sampleVector.end(),myfunction);
for (it=sampleVector.begin(); it!=sampleVector.end(); ++it) {
std::cout << *it << " "; <-- error must change it to &*it
}
Misplaced parenthesis. Correction:
sampleVector.erase( std::unique(sampleVector.begin(),sampleVector.end()),
sampleVector.end() );
I don't blame you for getting caught out. C++ compiler errors are heinous.
I think you can try this code below
bool myfunction (int i, int j) {
return (i==j);
}
std::unique (myvector.begin(), myvector.end(), myfunction);
std::cout << "myvector contains:";
for (it=myvector.begin(); it!=myvector.end(); ++it){
std::cout << ' ' << *it;
}
std::cout << '\n';
Hope it will help!
Another possibility worth considering is that you could put the sorted elements into an std::set. That will retain the sorted ordering and ensure item uniqueness.

C++ iterator behaviour in for vs while loops

I do not understand why iterating through a container with a for loop produces different results than iterating through it with a while loop. The following MWE illustrates this with a vector and a set of 5 integers.
#include <iostream>
#include <vector>
#include <set>
using namespace std;
int main()
{
vector<int> v;
set<int> s;
// add integers 0..5 to vector v and set s
for (int i = 0; i < 5; i++) {
v.push_back(i);
s.insert(i);
}
cout << "Iterating through vector with for loop.\n";
vector<int>::const_iterator itv;
for (itv = v.begin(); itv != v.end(); itv++) cout << *itv << ' ';
cout << '\n';
cout << "Iterating through set with for loop.\n";
set<int>::const_iterator its;
for (its = s.begin(); its != s.end(); its++) cout << *its << ' ';
cout << '\n';
cout << "Iterating through vector with while loop.\n";
itv = v.begin();
while (itv++ != v.end()) cout << *itv << ' ';
cout << '\n';
cout << "Iterating through set with while loop.\n";
its = s.begin();
while (its++ != s.end()) cout << *its << ' ';
cout << '\n';
}
The above produces:
Iterating through vector with for loop.
0 1 2 3 4
Iterating through set with for loop.
0 1 2 3 4
Iterating through vector with while loop.
1 2 3 4 0
Iterating through set with while loop.
1 2 3 4 5
The for loops work as expected but not the while loops. Since I'm using ++ as a postfix, I don't understand why the while loops behave as they do. Another mystery is why the while loop prints a 5 for set s, since this number was not inserted in s.
Your while loop is not equivalent to the for loop.
The for loop is equivalent to
itv = v.begin();
while(itv != v.end()) {
cout << *itv << ' ';
itv++;
}
Note that the increment happens after the cout. In your while loops, you do the increment in the test, before cout. Even though you use postincrement, the increment takes effect before your loop body is executed.
Write your while loops like I did there and the discrepancy should disappear.
When you iterate using the for loop you increment the iterator only after the body is evaluated. When you iterate using the while loop you increment the iterator after the check but before the body of the loop. Dereferencing the iterator in the last iteration of your while loops causes undefined behavior.
It could be because the compiler evaluates the its++ in the while expression first before evaluating the rest of the expression.
Since I'm using ++ as a postfix, I don't understand why the while loops behave as they do.
That's because first the while predicate is evaluated, and then (if the predicate was true) the body of the while loop. By the time you try to access the value in the body, the iterator was already incremented.
Just a few 'random' style hints, mainly showing algorithm use and modern C++11 features.
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <iterator>
int main()
{
const std::vector<int> v { 0,1,2,3,4 };
const std::set<int> s { 0,1,2,3,4 };
for (auto element : v)
std::cout << element << ' ';
std::cout << '\n';
for (auto element : s)
std::cout << element << ' ';
std::cout << '\n';
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
std::copy(s.begin(), s.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
}

STL vector usage problem -- Function returning non-zero Iterator

I was trying to use the vector STL, where iam facing a weird response from the following sample program :
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
vector<int>::iterator fun();
vector<int> myvector;
bool IsOdd (int i) {
return ((i%2)==1);
}
int main()
{
vector<int>::iterator it;
it = fun();
if (it == myvector.end() )
cout << "Reached end, Global" << endl;
else
cout << "Not end" << endl;
}
vector<int>::iterator fun() {
vector<int>::iterator it;
myvector.push_back(10);
myvector.push_back(26);
myvector.push_back(40);
myvector.push_back(56);
it = find_if (myvector.begin(), myvector.end(), IsOdd);
cout << "The first odd value is " << *it << endl;
if (it == myvector.end() )
cout << "Reached end, inside the function" << endl;
else
cout << "Not end" << endl;
return it;
}
Iam getting "Reached End" inside the function fun(), whereas, in the main program, it is showing up as "Not End".
Not sure, what might be the reason. Also, found that, the Address of myvector.end() is showing up as Zero in the main program [ after the fun() call ], where-as, showing a non-zero value inside the function fun().
The function is using the local myvector, main is using the global one.
Your modified code produces:
Reached end, inside the function
Reached end, Global
as expected.
Edit: Well, not as expected - as others have pointed out:
it = find_if (myvector.begin(), myvector.end(), IsOdd);
cout << "The first odd value is " << *it << endl;
will cause undefined behaviour with your dataset, because you don't have any odd values. You want:
it = find_if (myvector.begin(), myvector.end(), IsOdd);
if ( it != myvector.end() ) {
cout << "The first odd value is " << *it << endl;
}
There are two different myvectors, one is global, another is in fun. Therefore, you're comparing an iterator to the global vector with an iterator to a local vector which moreover doesn't exist anymore.
You have two instances of vector with name myvector. One global and one local to function fun. Inside fun this local vector hides the global vector. Since you are operating on two totally different vector objects you are seeing these results.
You dereferenced *it without checking if it was before the end. None of your vector values are odd, so it will be end and you will cause undefined behaviour by dereferencing it.