get more details from bad_alloc? - c++

since vector gets long unsigned int call to f(-1) throws bad_alloc. I suspect a call is made with 2147483648, actually 18446744073709551615 since it is x64 system. How can I get information about details of the error? This may be generalized, how can I get more details than e.what()?
void f(int i){
vector<int> v(i);
printf("vector size: %d", v.size());
}
int main(int argc, char** argv) {
//f(1); // vector size: 1
try{
f(-1); // terminate called after throwing an instance of 'std::bad_alloc'
//what(): std::bad_alloc
}catch(std::bad_alloc& e){
printf("tried to allocate: %d bytes in vector constructor", e.?);
}
return 0;
}

As far as the standard is concerned, there is no extra information other than what is provided by what() (whose content, by the way, is left to the implementation).
What you may do is to provide to vector your own allocator, that throws a class derived from bad_alloc but that also specifies the information you want to retrieve when catching it (e.g. the amount of memory required).

#include <vector>
#include <iostream>
template <typename T>
std::vector<T> make_vector(typename std::vector<T>::size_type size, const T init = T()) {
try {
return std::vector<T>(size, init);
}
catch (const std::bad_alloc) {
std::cerr << "Failed to allocate: " << size << std::endl;
throw;
}
}
int main()
{
make_vector<int>(std::size_t(-1));
return 0;
}
A reserve instead of initialization might suit better.
Please have copy elision/return value optimization and move in mind.

Related

How to cause a length_error exception in C++

I am trying to make code that throws a length_error exception. My goal is to detect and handle this exception condition. This is my attempt so far:
#include <iostream>
#include <string>
using namespace std;
int main(int argc, const char * argv[])
{
string buffer("hi");
cout<<buffer.max_size()<<endl;
try {
while(1) {
buffer.append(buffer);
}
}
catch(length_error &l) {
cout<<"Caught length_error exception: "<<l.what()<<endl;
}
catch(exception &e) {
cout<<"Caught exception: "<<e.what()<<endl;
}
return 0;
}
When I run the program I see the max size of the string is 18446744073709551599 bytes. The program continues running until all the memory is used up. Then it just goes quiet. No exception is thrown. The program is still running but its CPU usage went from 100% to around 0%.
Additional information:
OS: Mac OS 10.8.
Compiler: Clang 5.1
RAM: 16 GB
I believe your machine is going into virtual memory thrashing due to the memory consumption of growing your string by two characters a LOT of times.
A more effective way of getting this exception is to create a string of size max_size()+1 at the outset. Here's your code modified to do this, and (for me, at least) it throws the exception you expect instantly:
#include <iostream>
#include <string>
using namespace std;
int main(int argc, const char * argv[])
{
string buffer("hi");
cout<<buffer.max_size()<<endl;
try {
std::string blah(buffer.max_size()+1, 'X');
}
catch(length_error &l) {
cout<<"Caught length_error exception: "<<l.what()<<endl;
}
catch(exception &e) {
cout<<"Caught exception: "<<e.what()<<endl;
}
return 0;
}
std::length_error is only thrown in a case where a buffer size is known to exceed the container's max_size().
On a modern operating system with virtual memory, it's unlikely to request something that exceeds max_size() unless by accident (such as through negative unsigned values), and so the approach you are taking is unlikely to see this exception thrown. Instead, since you're using append, you're likely going to just use virtual memory by paging out to disk after you have exhausted your real memory -- which will slow the system down.
If you want to trigger a length_error, the easiest way would be to pass something greater than max_size() (assuming this is smaller than std::numeric_limits<std::string::size_type>::max()). You should be able to just do something like:
auto str = std::string{};
str.reserve(static_cast<std::string::size_type>(-1));
or
auto str = std::string{};
str.reserve(str.max_size()+1);

is it ok to return a local variable by move?

I'm reading Nicolai M. Josuttis's 2nd edition of "The C++ Standard Library" covering C++11 , where in Chapter 18: Concurrency, page 969 and 970 give a sample program:
// concurrency/promise1.cpp
#include <thread>
#include <future>
#include <iostream>
#include <string>
#include <exception>
#include <stdexcept>
#include <functional>
#include <utility>
void doSomething (std::promise<std::string>& p)
{
try {
// read character and throw exceptiopn if ’x’
std::cout << "read char (’x’ for exception): ";
char c = std::cin.get();
if (c == ’x’) {
throw std::runtime_error(std::string("char ")+c+" read");
}
...
std::string s = std::string("char ") + c + " processed";
p.set_value(std::move(s)); // store result
}
catch (...) {
p.set_exception(std::current_exception()); // store exception
}
}
int main()
{
try {
// start thread using a promise to store the outcome
std::promise<std::string> p;
std::thread t(doSomething,std::ref(p));
t.detach();
...
// create a future to process the outcome
std::future<std::string> f(p.get_future());
// process the outcome
std::cout << "result: " << f.get() << std::endl;
}
catch (const std::exception& e) {
std::cerr << "EXCEPTION: " << e.what() << std::endl;
}
catch (...) {
std::cerr << "EXCEPTION " << std::endl;
}
}
Here string s is a local variable but moved to return.
However, as programs quited calltree level by level, the stack memory will be release. Would this be a problem when call stack unwinds?
Note: this question is different from c++11 Return value optimization or move? : this question is about move is potentially dangerous, while the other question is about whether actively prohibits copy elision or let compiler decide.
Unless otherwise specified, all standard library objects that have been moved from are placed in a valid but unspecified state. Valid means it can be safely destroyed (e.g on stack unwinding). In your example s is not returned but stored in promise but if it was returned in normal way return s; compiler could implicitly call return move(s);.
This is not a problem.
Move semantics moves the internal value of a variable not the variable itself. So you still have a separate destination string to the source string.
The whole exercise works ostensibly like a copy except that afterwards the source object has changed its value to an unknown quantity.
It is still a valid object (of unknown value) and will be properly destroyed when the stack unwinds.

Testing for proper behaviour on memory allocation failures

We have a relatively large code base for a Linux server, it's dynamically linked-in libraries and server modules loaded during startup using dlopen(). The server as well as most of the other components are written in C++11, but some are in C99.
What approaches could one use to test whether the server, its dependencies and modules properly handle memory allocation failures, e.g.malloc/calloc returning NULL, operators new and new[] throwing std::bad_alloc etc, including allocation failures from std::string::resize() and such?
In the past, I've tried using memory allocation hooks to inject memory allocation failures into C applications, but I think these don't work for C++. What other options or approaches should I be looking at?
In fact, hooking into C malloc is enough, since under the hood the gcc C++ default implementation of operator new does call malloc and you confirmed you only needed a gcc compatible solution.
I could demonstrate it with that simple program:
mem.c++:
#include <iostream>
#include <string>
class A {
int ival;
std::string str;
public:
A(int i, std::string s): ival(i), str(s) {}
A(): ival(0), str("") {};
int getIval() const {
return ival;
}
std::string getStr() const {
return str;
}
};
int main() {
A a(2, "foo");
std::cout << &a << " : " << a.getIval() << " - " << a.getStr() << std::endl;
return 0;
}
memhook.c:
#include <stdio.h>
#include <stdlib.h>
extern void *__libc_malloc(size_t size);
void* malloc (size_t size) {
fprintf(stderr, "Allocating %u\n", size);
return NULL;
// return __libc_malloc(size);
}
When returning NULL (as above), the program displays:
Allocating 16
Allocating 100
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Abandon (core dumped)
That proves that returning NULL from the declared malloc function results in a std::bad_alloc exception in C++ code
When uncommenting the return __libc_malloc(size); the allocations are done by the libc malloc and the output becomes:
Allocating 16
0xbfe8d2e8 : 2 - foo
On linux you can hook into the operating system to force allocation to fail
man 2 mlockall
mlockall(MCL_CURRENT|MCL_FUTURE);
Should do what you want.

MSVC 14 STL vector reserve

I have noticed strange behavior (IMO) on MSVC 14 Comm. in Debug x86 solution.
Code below throws Exception when vector::resize is not included.
Note: after assigment some entities may be unassigned by passing nullptr.
vector<Entity*> m_entities;
(...)
// find empty slot
u_int id = m_entities.size();
for(u_int i=0; i<m_entities.size(); ++i)
{
if(m_entities[i] == nullptr)
{
id = i;
break;
}
}
// vector realloc
if(id == m_entities.capacity())
{
u_int newSize = m_entities.capacity() * 2;
m_entities.reserve(newSize);
//m_entities.resize(newSize);
}
// assign
entity->m_id = id;
m_entities[id] = entity;
It looks like operator[] checks size() instead of capacity() - am I right?
You can NOT access the reserved area of the vector if it was not initialized. reserve does not initialize anything it just reserve (as it was named) some memory to not reallocate the vector each time a new item is pushed back
Try to run this code:
#include <iostream>
#include <string>
#include <vector>
class my_class{
public:
my_class(){
x="I am an initialized item";
}
std::string x;
};
int main()
{
std::vector<my_class> v(2);
v.reserve(3);
std::cout << v[0].x <<std::endl<< v[1].x <<std::endl <<v[2].x;
}
You may got compiling error in the debug mode(depending on your compiler), it may pass and give undefined behaviour (NOT sure about undefined behaviour please someone edit this part). In best case, it would run with printing empty string for v[2].
Live Demo

exception handling a constructor

This was an interview question of me.
Surprisingly i never thought of this kinda question to myself.
can we have exception handling inside a constructor c++?
in tense and not thinking much i said "yes we could probably do it in a constructor.lets say we are allocating some memory using new operator to a pointer member and it throws a bad alloc exception,in this way there is a possibility of exceptions being raised"
Then later i thought that constructors can never return a value.So how can an exception inside a constructor caught.now i am asking this to myself!
can anybody pls help me to come out of this confusion?
See this GOTW Constructor Failures question which addresses your query somewhat and goes on to say it is a waste of time.
Constructors don't have a return type,
so it's not possible to use return
codes. The best way to signal
constructor failure is therefore to
throw an exception. If you don't have
the option of using exceptions, the
"least bad" work-around is to put the
object into a "zombie" state by
setting an internal status bit so the
object acts sort of like it's dead
even though it is technically still
alive.
You would catch the exception in the calling code, not within the constructor.
See How can I handle a constructor that fails? for further details (actually, I'd suggest reading the whole page about exception handling, truly enlightening).
Exception handling and return type are completely different. when the program find the exception in constructor, it throws the exception to nearly by catch block [if used] or thrown to caller (main()). in this case, we have catch block in constructor and exception handled by it. Once exception handled, the remaining statement in the constructor/function will be started executing. see the below example,
class A
{
public:
A(){
printf("Hi Constructor of A\n");
try
{
throw 10;
}
catch(...)
{
printf("the String is unexpected one in constructor\n");
}
printf("Hi Constructor of A\n");
}
~A(){
printf("Hi destructor of A\n");
}
};
int main()
{
try{
A obj ;
throw "Bad allocation";
}
catch(int i)
{
printf("the Exception if Integer is = %d\n", i);
}
catch(double i)
{
printf("the Exception if double is = %f\n", i);
}
catch(A *objE)
{
printf("the Exception if Object \n");
}
catch(...)
{
printf("the Exception if character/string \n");
}
printf("Code ends\n");
return 0;
}
This produce Output:
Start: Constructor of A
the String is unexpected one in constructor
End: Constructor of A
Hi destructor of A
the Exception if character/string
Code ends
C++ has try-catch clauses similar to those of other languages. A tutorial can be found online: http://www.cplusplus.com/doc/tutorial/exceptions/
EDIT: example turned into fully working code
#include <iostream>
using namespace std;
class A
{
public:
void f(){
throw 10;
}
A(){
try{
f();
}
catch(int e){
cout << "Exception caught\n";
}
}
};
int main (int argc, const char * argv[])
{
A a;
return 0;
}
This produces output:
Exception caught