Debug assertion failed in Visual Studio but runs OK on online IDE - c++

My code runs fine when I run it on online IDEs but fails with debug assertion error when run on visual studio. The error is probably in the rand() function because when I specifically use random integer values, it works just fine. I don't understand why is it not running on VS.
The following message is being displayed:
Debug Assertion Failed!
Program: [Path]
Line: 1639
Expression : sequence not ordered
Also I'd like to ask how to debug these errors as they are not specifying a particular code instance.
#include <iostream>
#include <list>
#include <cstdlib> //for rand() function
using namespace std;
void display(list <int> &lst)
{
list <int> ::iterator p;
for (p = lst.begin(); p != lst.end(); p++)
{
cout << *p << " ";
}
cout << "\n\n";
}
int main()
{
list <int> list1; //empty list of zero length
list <int> list2(5); //empty list of size 5
for (int i = 0; i < 3; i++)
{
list1.push_back(rand() % 100);
}
list <int> ::iterator p;
for (p = list2.begin(); p != list2.end(); p++)
{
*p = (rand() % 100);
}
cout << "List1: ";
display(list1);
cout << endl << endl;
cout << "List2: ";
display(list2);
cout << endl << endl;
//Add two elements at the ends of list 1
list1.push_back(200);
list1.push_front(100);
//Remove an element at the front of list 2
list2.pop_front();
cout << "Now list1: ";
display(list1);
cout << "\n\n";
cout << "Now list2: ";
display(list2);
cout << "\n\n";
list<int> listA, listB;
listA = list1;
listB = list2;
//Merging two lists(unsorted)
list1.merge(list2);
cout << "Merged unsorted lists\n";
display(list1);
cout << "\n\n";
//Sorting and merging
listA.sort();
listB.sort();
listA.merge(listB);
cout << "Merged sorted lists\n";
display(listA);
cout << "\n\n";
//Reversing a list
listA.reverse();
cout << "Reversed merged list: \n";
display(listA);
return 0;
}

merge requires that the lists be sorted (see: https://en.cppreference.com/w/cpp/container/list/merge). In your first call to merge the lists are not sorted (the lists are only sorted prior to your second call).
In debug mode, the Microsoft C++ standard libraries include extra runtime checks to enforce invariants such as this. The "Online IDE" likely uses GCC with libstdc++ or similar which generally does not include the same level of runtime checking that the Microsoft libraries do, and therefore does not catch the mistake.

Documentation of list::merge says:
Exception safety
If the allocators in both containers do not compare equal, if comp does not define a strict weak ordering, or if the container elements
are not ordered according to it, it causes undefined behavior.
Otherwise, if an exception is thrown by a comparison, the container is
left in a valid state (basic guarantee). Otherwise, if an exception is
thrown, there are no changes in the container (strong guarantee).
So depending on compiler implementation behavior can be different when merging unsorted lists. Apparently Visual Studio does extra checking in debug mode which is not required (but allowed) by C++ standard.

Related

frequency <unordered_map> behaviour

i try to implement freq unordered map but it has weird behavior , why when i use unordered_map it gives me keys with negative numbers and when i use map it will give my the correct keys values.
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int maxOperations(vector<int>& nums, int k) {
unordered_map <int,int> mp;
for(auto i:nums){
mp[i]++;
}
int count=0;
// for(auto i:mp)
// cout << i.first << " " << i.second << endl;
for(auto i:mp){
int target= k-i.first;
cout << i.first << " " << i.second << " "<< mp[target] << endl;
if(i.second>0 && mp[target]>0){
if(i.first!=target){
count += min(i.second,mp[target]);
mp[target]=0;
//i.second=0;
mp[i.first]=0;
}else
{
cout << count << endl;
count += floor(i.second/2);
mp[target]=0;
}
}
}
return count;}
int main()
{
vector<int> vec= {29,26,81,70,75,4,48,38,22,10,51,62,17,50,7,7,24,61,54,44,30,29,66,83,6,45,24,49,42,31,10,6,88,48,34,10,54,56,80,41,19};
int k =12 ;
cout << maxOperations(vec,k);
return 0;
}
When you use an ordered map, you traverse the keys in order. Thus, target is never negative. When you traverse an unordered map, it is unordered. Therefore, target is sometimes negative.
If the negative values are not correct, then you need to traverse the map in order and so you should not use an unordered map.
Another problem with traversing out of order is that when modifying the map while traversing it, you will create entries that may or may not be included in your traversal. That will cause unpredictable behavior. You may prefer to create new entries in a separate container and merge them into the original container only when you're finished traversing.

Visual Studio does not show in which line error is

When I am programming in C++ and Visual Studio 2019 throws an error, it shows in which line it was encountered. But when coding with C++ when error is thrown, it does not show in which line exactly it appears. So it makes hard to debug and fix my program. Maybe there are settings that I need to adjust?
C++ error (it point to some 1501 line of installation files that weren't created by me):
vector<int> myVector(2);
cout << myVector[4] << endl;
Errors in both programs in these examples are of a same category: vector (in C++).
Without providing more code and looking at the minimal c++ code you provided:
vector<int> myVector(2);
cout << myVector[4] << endl;
It looks like you have too many elements in myVector in the second line. You will have UB because the [] operator does not allocated more elements. You only declared 2 elements.
Now, when you send your vector to cout you are saying you have 4 which is false.
That is why you are getting the error: "Expression: vector subscript out of range".
You only have two indices 0 and 1, if you define a vector with 2 elements.
Now if you were trying to see the size of your vector you use the .size() function which returns the number of elements in the vector.
vector<int> myVector(2);
cout << myVector.size() << endl;
You could even do something like this with a for loop:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> myVector(2);
std::cout << myVector.size() << std::endl;
for (int i = 0; i < 10; i++)
myVector.push_back(i);
std::cout << myVector.size() << '\n';
return 0;
}

What is the most efficient way of outputting strings stored in a stack but with the letters of the strings reversed in order?

What the program does is allows the user to input a bunch of strings, stores them in a stack, and then outputs all of those strings in the stack but in reverse order and flipped. Is there a more efficient way of doing what I did? Maybe using a different data structure (other than a stack)? I though a stack would be best because the strings stored in the stacks need to be outputted in the opposite order that they were inputted.
Here's the code:
#include <iostream>
#include <stack>
using namespace std;
int main() {
stack <string> elements;
string element;
cout << "Hello, welcome to Flippy-McBackwardson! \n\n" << endl;
cout << "Please enter a bunch of strings (type END to terminate your list): " << endl;
do {
getline(cin, element);
elements.push(element);
} while (element != "END");
elements.pop();
cout << "\nFlippy Backward Version: " << endl;
for (int x = elements.size()-1; x >= 0; x--){
for (int i = elements.top().length()-1; i >= 0; i--){
cout << elements.top()[i];
}
elements.pop();
cout << endl;
}
return 0;
}
You can use reverse iterators (accessible using std::rbegin() and std::rend()) which should be cleaner and safer as they don't involve tricky subscripting math that is prone to off-by-one errors (at the very least).
while(!elements.empty())
{
std::for_each(std::rbegin(elements.top()), std::rend(elements.top()),
[](char c){ std::cout << c; });
std::cout << '\n';
elements.pop();
}

std vector does not throw out_of_range exception when accessing uninitialized elements [duplicate]

This question already has answers here:
Vector going out of bounds without giving error
(4 answers)
Closed 5 years ago.
I read this tutorial
std::vector beginners tutorial
and also saw this question:
similar tpoic question
Yet, when I run my simple example I did not see the excepted results, which are --> an std::out_of_range exception is NOT thrown.
Did I misunderstand here something ?
The sample code I run is the following (the code run and terminates successfully, i.e.- no exceptions thrown):
#include <iostream>
#include <vector>
using namespace std;
class MyObjNoDefualtCtor
{
public:
MyObjNoDefualtCtor(int a) : m_a(a)
{
cout << "MyObjNoDefualtCtor::MyObjNoDefualtCtor - setting m_a to:" << m_a << endl;
}
MyObjNoDefualtCtor(const MyObjNoDefualtCtor& other) : m_a(other.m_a)
{
cout << "MyObjNoDefualtCtor::copy_ctor - setting m_a to:" << m_a << endl;
}
~MyObjNoDefualtCtor()
{
cout << "MyObjNoDefualtCtor::~MyObjNoDefualtCtor - address is" << this << endl;
}
// just to be sure - explicitly disable the defualt ctor
MyObjNoDefualtCtor() = delete;
int m_a;
};
int main(int argc, char** argv)
{
// create a vector and reserve 10 int's for it
// NOTE: no insertion (of any type) has been made into the vector.
vector<int> vec1;
vec1.reserve(10);
// try to access the first element - due to the fact that I did not inserted NOT even a single
// element to the vector, I would except here an exception to be thrown.
size_t index = 0;
cout << "vec1[" << index << "]:" << vec1[index] << endl;
// now try to access the last element - here as well: due to the fact that I did not inserted NOT even a single
// element to the vector, I would excpet here an excpetion to be thrown.
index = 9;
cout << "vec1[" << index << "]:" << vec1[index] << endl;
// same thing goes for user defined type (MyObjNoDefualtCtor) as well
vector<MyObjNoDefualtCtor> vec2;
vec2.reserve(10);
// try to access the first element - due to the fact that I did not inserted NOT even a single
// element to the vector, I would except here an exception to be thrown.
index = 0;
cout << "vec2[" << index << "]:" << vec2[index].m_a << endl;
// now try to access the last element - here as well: due to the fact that I did not inserted NOT even a single
// element to the vector, I would except here an exception to be thrown.
index = 9;
cout << "vec2[" << index << "]:" << vec2[index].m_a << endl;
return 0;
}
Notes:
The sample code is compiled with -std=c++11 option.
Compiler version is g++ 5.4 (on my Ubuntu 16.04 machine).
Thanks,
Guy.
A vectors operator[] function may or may not do bounds-checking. The implementations that do have bounds-checking, typically only does it for debug-builds. GCC and its standard library doesn't.
The at function on the other hand, does have mandatory bounds-checking and will be guaranteed to throw an out_of_range exception.
What happens here is simply that you go out of bounds and have undefined behavior.
Is at() that perform the range check, not (necessarily) operator[].
Your code have udefinded behaviour.
If you want to be sure to get an exception, use
vec1.at(index)
instead of
vec1[index]

C++ cout statements not displayed during a for loop when launched from command line

I am writing code for a project in my computer science course and I am testing my algorithm to see if it works and how fast it is. I know that the algorithm works because when I launch the program in Visual Studio 2013, I get the correct output. But, when I launch the .exe from the Visual Studio projects folder in the command line or from windows explorer, the first two cout statements are displayed correctly, but the cout statements during the for loop are not displayed at all. Again this only happens when I launch the .exe outside of Visual Studio. It isn't a big problem, but I wonder what's going on here. Thanks.
Here is int main() (The first 2 couts work and the others don't):
int main() {
// declare input stream for reading dctnryWords.txt
ifstream inFile;
// create a pointer to memory in the heap
// where each word in the dictionary will be stored
string* words = new string[DICTIONARY_SIZE];
// create a vector of forward_lists to hold
// adjacent words for each word in the dictionary
vector< list<string> > adjacents(DICTIONARY_SIZE);
// open dctnryWords.txt
inFile.open("dctnryWords.txt");
// load words into RAM
cout << "Loading words into RAM took: "
<< time_call([&] { copyDictionary(inFile, words); })
<< "ms\n";
cout << "Finding adjacent words took: "
<< time_call([&] { searchAdjacents(words, adjacents); })
<< "ms\n";
for (int i = 0; i < DICTIONARY_SIZE; i++) {
if (adjacents[i].size() >= 25) {
cout << words[i] << "(" << adjacents[i].size()
<< "): ";
for (list<string>::const_iterator j = adjacents[i].cbegin(); j != adjacents[i].cend(); j++) {
cout << *j << " ";
}
cout << endl << endl;
}
}
return 0;
}
I'll bet a nickel your program isn't finding "dctnryWords.txt" when you launch it elsewhere... because it's going to look in the current directory, which is likely different when you run it outside of VS.