Which vector threw index out of range exception? - c++

I would like to access a reference to the std::vector which throws an out of range exception, or at least the line number where the exception was thrown (similar to Java's stack traces). Here is an example program:
#include <iostream>
#include <vector>
std::vector<int> vec1;
std::vector<int> vec2;
vec1.push_back(1);
vec2.push_back(2);
try
{
std::cout << vec1.at(1) << std::endl;
std::cout << vec2.at(1) << std::endl;
}
catch(Exception e)
{
// e.lineNumber()? e.creator_object()?
std::cout << "The following vector is out of range: " << ? << std::endl;
// or...
std::cout << "There was an error on the following line: " << ? << std::endl;
}
I know this example is trivial, but I hope it demonstrates what functionality I'm looking for.
EDIT: Implementation, from g++ --version: g++ (GCC) 4.1.2 20071124 (Red Hat 4.1.2-42)

You will need to do that yourself:
#include <iostream>
#include <vector>
std::vector<int> vec1;
std::vector<int> vec2;
vec1.push_back(1);
vec2.push_back(2);
try
{
std::cout << vec1.at(1) << std::endl;
}
catch(std::exception& e)
{
std::cout << "The following vector is out of range: " << "vec1" << std::endl;
}
try
{
std::cout << vec2.at(1) << std::endl;
}
catch(std::exception& ex)
{
std::cout << "The following vector is out of range: " << "vec2" << std::endl;
}

Related

Flexible number of fields during Automatic Conversion from JSON boost-1.81.0

Is it possible to convert from a json to a structure with boost-json,
boost-describe if some fields are missing in the json or it has some extra
unneeded fields. In other words to make the json parser a bit more flexible.
The example is taken from https://www.boost.org/doc/libs/1_81_0/libs/describe/doc/html/describe.html#example_from_json with some modification and the templates are removed as I understood they are part of the headers right now.
Here is the code example:
#include <iostream>
#include <boost/describe.hpp>
#include <boost/json/src.hpp>
using namespace std;
struct A {
optional<int> x;
optional<string> y;
};
BOOST_DESCRIBE_STRUCT(A, (), (x, y))
int main()
{
try {
auto json_val = boost::json::parse(R"({"x":5,"y":"Hello world!"})");
auto a = boost::json::value_to<A>(json_val);
cout << "a.x=" << *a.x << ", a1.y=" << *a.y << endl;
}
catch (exception& e) {
cout << e.what() << endl;
}
// error
try {
auto json_val = boost::json::parse(R"({"x":5})");
auto a = boost::json::value_to<A>(json_val); // << exception is here
cout << "a.x=" << *a.x << endl;
}
catch (exception& e) {
cout << e.what() << endl;
}
// error
try {
auto json_val =
boost::json::parse(R"({"x":5,"y":"Hello world!","z":3.1})");
auto a = boost::json::value_to<A>(json_val); // << exception is here
cout << "a.x=" << *a.x << ", a1.y=" << *a.y << endl;
}
catch (exception& e) {
cout << e.what() << endl;
}
}
the output is
[it#test-dev refl1]$ make
g++ -g -O0 -std=c++20 -I/home/it/Snb/boost/1.81.0/include -c -o test1.o test1.cpp
g++ -o test1 test1.o
[it#test-dev refl1]$ ./test1
a.x=5, a1.y=Hello world!
array size does not match target size [boost.json:31 at /home/it/Snb/boost/1.81.0/include/boost/json/detail/value_to.hpp:533:9 in function 'boost::json::result<T> boost::json::detail::value_to_impl(boost::json::try_value_to_tag<T>, const boost::json::value&, boost::json::detail::described_class_conversion_tag)']
array size does not match target size [boost.json:31 at /home/it/Snb/boost/1.81.0/include/boost/json/detail/value_to.hpp:533:9 in function 'boost::json::result<T> boost::json::detail::value_to_impl(boost::json::try_value_to_tag<T>, const boost::json::value&, boost::json::detail::described_class_conversion_tag)']

Iterating over a QHash VS std::unordered_map

#include <iostream>
#include <map>
#include <unordered_map>
#include <QHash>
#include <QMap>
#include <QString>
void _QMap()
{
QMap<int, QString> amap;
amap.insert(2, "cdasdc");
amap.insert(1, "cda");
amap.insert(3, "zzz");
std::cout << std::endl;
auto i = amap.begin();
while (i != amap.end())
std::cout << i.key() << " " << i++.value().toStdString() << std::endl;
}
void _map()
{
std::map<int, std::string> bmap;
std::pair<int, std::string> val(2, "cdasdc");
bmap.insert({1, "cda"});
bmap.insert({3, "zzz"});
bmap.insert(val);
std::cout << std::endl;
for (auto& i : bmap)
std::cout << i.first << " "<< i.second << std::endl;
}
void _QHash()
{
QHash<int, QString> ahash;
ahash.insert(2, "cdasdc");
ahash.insert(1, "cd");
ahash.insert(3, "zzz");
std::cout << std::endl;
auto i = ahash.begin();
while (i != ahash.end())
std::cout << i.key() << " " << i++.value().toStdString() << std::endl;
}
void _hash()
{
std::unordered_map<int, std::string> ahash;
ahash.insert({2, "cdasdc"});
ahash.insert({1, "cd"});
ahash.insert({3, "zzz"});
std::cout << std::endl;
for (auto& i : ahash)
std::cout << i.first << " "<< i.second << std::endl;
}
int main()
{
_QMap();
_map();
_QHash();
_hash();
}
I run above code multiple times and observed the output. The _QHash() print is different each time, which I was expecting since documentation says the items are arbitrarily ordered.
I was expecting QHash and std::unordered_map to behave the same way since documentation says the elements are not sorted.
However _hash() print is always the same. Why?
see https://doc.qt.io/qt-6/qhash.html#algorithmic-complexity-attacks
"In order to avoid this worst-case behavior, the calculation of the hash value done by qHash() can be salted by a random seed, that nullifies the attack's extent. This seed is automatically generated by QHash once per process, and then passed by QHash as the second argument of the two-arguments overload of the qHash() function.

Why does this basic Try-Catch fail to catch [duplicate]

This question already has answers here:
Why doesn't 'd /= d' throw a division by zero exception when d == 0?
(5 answers)
Closed 1 year ago.
I am learning about try-catch constructs in C++ and I have the following example that appears to fail to execute the code inside either of the catches. I have spent the past few hours trying to find the bug/issue without luck.
I am wondering if there is an issue with g++ on my machine -- I am using mingw's g++ and Windows 10.
#include <iostream>
#include <stdexcept>
int main(){
try {
std::cout << "Start of Try-Catch\n";
int a = 13;
int b = 0;
int p = a/b;
std::cout << "printing p: " << p << std::endl;
p = 43;
std::cout << "Passed the div by zero issue\n";
} catch (std::runtime_error& e){
std::cout << "runtime error: " << e.what() << '\n';
return 2;
} catch (std::exception& e){
std::cout << "other error: " << e.what() << '\n';
return 3;
} catch (...) {
std::cout << "final catch\n";
return 4;
}
std::cout << "end of program\n";
return 0;
}
Instead, this is what happens when I compile and run:
C:\Users\...\Part 1>g++ cp_bug.cpp -std=c++17
C:\Users\...\Part 1>a.exe
Start of Try-Catch
C:\Users\...\Part 1>
it would be more logical to do something like that:
int main(){
try {
std::cout << "Start of Try-Catch\n";
int a = 13;
int b = 0;
if(b==0)
throw std::string("Passed the div by zero issue\n");
int p = a/b;
std::cout << "printing p: " << p << std::endl;
} catch (std::string e) {
std::cout << e;
return -1;
}
std::cout << "end of program\n";
return 0;
}
Your problem is that division by zero doesn't throw an exception that can be handled. Try the following tutorial instead.
Also this question is duplicated.

Moving element from container does not empty container?

Given the following code:
#include <vector>
#include <iostream>
struct number {
int n{666};
};
int main()
{
std::vector<number> vec;
std::cerr << vec.size() << std::endl;
number n;
vec.push_back(n);
std::cerr << vec.size() << std::endl;
auto b = std::move(vec.front());
std::cerr << "b: " << b.n << std::endl;
std::cerr << vec.size() << std::endl;
}
I get the following output:
0
1
b: 666
1
Shouldn't the last 1 be 0?
std::move doesn't even know that the thing it moved was in a container. The block of memory that the vector owns is still there, just in an unspecified state. It's up to you to manage the vector.
Once you have used the value at the front and you want to get rid of it you will need to erase it from the vector. I won't talk about the front() returning a ref as 0x5453 mentioned that. But there is no reason to use std::move there - all that does is cast the value to a rvalue reference it does not actually "move" anything on its own.
#include <vector>
#include <iostream>
struct number {
int n{666};
};
int main()
{
std::vector<number> vec;
std::cerr << vec.size() << std::endl;
number n;
vec.push_back(n);
std::cerr << vec.size() << std::endl;
// Since this is a ref, and your struct is simple - just copy
auto b {vec.front()};
// Now remove the element
vec.erase(vec.begin());
std::cerr << "b: " << b.n << std::endl;
std::cerr << vec.size() << std::endl;
}

c++ No exception thrown while expecting out_of_range

Consider the following source:
void ex8()
{
vector<int> v;
try
{
v.push_back(3);
int i = v[1];
}
catch (exception& e)
{
cout << "pas bon !";
}
}
When executing, no exception is thrown in Release. In Debug, I get a Debug Assertion Failed dialog.
I'am using Visual Studio on Win 10.
Is the vector implementation not supposed to throw an out_of_range exception?
Thank you.
Just an example with [] and at()
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v;
v.push_back(123);
v.resize(0);
try {
std::cout << "at() ";
std::cout << v.at(0) << std::endl;
}
catch (std::exception e) {
std::cout << e.what() << std::endl;
}
std::cout << "[] " << v[0] << std::endl; // all can append
return 0;
}
For me the execution is
at() std::exception
[] 123