Thread: Catch std::bad_alloc of a vector constructed inside a member initializer list

  1. #1
    Registered User
    Join Date
    Mar 2020
    Posts
    11

    Catch std::bad_alloc of a vector constructed inside a member initializer list

    Hi!
    I am dealing with a problem in which I have to allocate a huge distance matrix (~600 GB on a cluster node). In order to save some memory, since the matrix is symmetric, I defined an upper triangular class as follows:

    Code:
    class utriag_matrix {
        uint32_t dim;
        std::vector<double> buffer;
        public:
        utriag_matrix(uint32_t d): dim(d), buffer( ( (d*(d-1))/2 ) ,0 ){}
        
        uint32_t size() {return dim;}
    
        double& at(uint32_t i, uint32_t j)
        {
            if(i==j){ throw std::invalid_argument( "at(i,j) with i == j is not a valid element of utriag_matrix." );}
            if (i>j){std::swap(i,j);}
            return buffer[dim*i - (i*(i+1))/2 - i + j - 1 ];
        }
    };
    Note that the internal buffer is an std::vector.

    The problem I think I am having is that the system is not able to allocate the std::vector even though I have more than enough RAM (the node has 1.5 TB of RAM so I am not even using half of it).

    Is there a way of catching a std::bad_alloc of a vector constructed inside a member initializer list?

    Is it a problem to allocate an std::vector of hundreds of GBs if my RAM is big enough (this is the first time I work with this amount of RAM)?

    Thanks in advance!

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Fede
    Is there a way of catching a std::bad_alloc of a vector constructed inside a member initializer list?
    Yes, you could use a function try block. However, in the case of a constructor, the catch block must always throw an exception, so you cannot really recover from an exception propagated by the member initialiser list: it is always a constructor failure; the function try block is more for stuff like logging or translating the exception.

    Quote Originally Posted by Fede
    I have more than enough RAM (the node has 1.5 TB of RAM so I am not even using half of it).
    That is an impressive amount of RAM.

    Quote Originally Posted by Fede
    Is it a problem to allocate an std::vector of hundreds of GBs if my RAM is big enough (this is the first time I work with this amount of RAM)?
    One possibility is that you may have more than enough memory available in total, but you might not have enough memory available contiguously.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Substitute your value of d.
    Code:
    #include <iostream>
    #include <vector>
    
    int main() {
      size_t d = 1000;
      std::vector<double> buffer( ( (d*(d-1))/2 ), 0 );
      std::cout << "Size=" << buffer.size() << std::endl;
    }
    Does it work?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Mar 2020
    Posts
    11
    Thanks for the replies.

    Yes, you could use a function try block. However, in the case of a constructor, the catch block must always throw an exception, so you cannot really recover from an exception propagated by the member initialiser list: it is always a constructor failure; the function try block is more for stuff like logging or translating the exception.
    I don't care about not recovering from the exception but I would like to have warnings printed to std::cerr. The implementation would be to include the try block inside the member initialization list?

    Regarding Salem's reply, while checking the code I did notice that uint32_t for the dimension could be the problem. I had already launched a set of benchmarks which includes this suggested modification among others.
    I'll know the results in a few hours although now that I read your reply I am almost certain that this was the problem. I'll update the thread once I know the result of the tests.

    Once again thanks for the help!

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > I am dealing with a problem in which I have to allocate a huge distance matrix (~600 GB on a cluster node)
    Yeah, uint32 is nowhere near large enough for doing calculations up to 600GB.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Mar 2020
    Posts
    11
    Effectively the problem was the uint32 was overflowing when calculating the buffer size: (d*(d-1))/2 ) with d~500000
    A mistake I do constantly
    Thanks for the replies!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. initialize member array in initializer list?
    By Vick jr in forum C++ Programming
    Replies: 4
    Last Post: 05-20-2010, 06:39 AM
  2. Replies: 10
    Last Post: 08-27-2009, 09:58 AM
  3. Accessing Member Methods inside a Vector
    By xmltorrent in forum C++ Programming
    Replies: 5
    Last Post: 06-23-2008, 12:02 PM
  4. Vector class throws bad_alloc
    By animeaholic in forum C++ Programming
    Replies: 7
    Last Post: 04-28-2008, 01:48 AM
  5. calling a member function inside a vector
    By finnepower in forum C++ Programming
    Replies: 2
    Last Post: 05-16-2004, 02:44 AM

Tags for this Thread