2

I got a problem with the following code, which I can't solve since hours... I'm glad for any kind of advice.

The types are defined as follows:

typedef std::vector< cv::RotatedRect > ds_t;

typedef struct id_ {
std::string path;
std::string fileName;
} id_t;

typedef struct dd_ {
    cv::RotatedRect bB;
} dd_t;

typedef std::pair<id_t, std::vector<dd_t> > ts_t;

typedef std::vector<ts_t> tss_t;

Then I try to fill the type with data:

tss_t samples
while (readdir(pDir) != NULL) {
     ts_t sample;
     sample.first.path = _path;
     sample.first.fileName = _name;
     ds_t detections;
     getDetections(_path, detections); //this only filles the detecions byref
     for(size_t i=0; i<detections.size(); i++) {
         dd_t data;
         data.bB = detections[i];
         sample.second.push_back(data); //TODO FIXME
     }
     samples.push_back(sample);
 }

cv::RotatedRect is a very basic class.

class RotatedRect{
   public:
   RotatedRect();
   RotatedRect(const Point2f& _center, const Size2f& _size, float _angle);
   void points(Point2f pts[]) const;

   Point2f center;
   Size2f size;
   float angle; 
};

bool getDetections(const std::string &imagePath, ds_t &detections)
{
  //some processing
  for(size_t i=0;i<5;i++)
    detections.push_back(RotatedRect(cv::Point2f(110.,110.), cv::Size2f(10.,10.), 90.0f));

  return true;
}

Hopefully I copied the whole code and I know, I don't need most of the typedefs...

I have already tried to reserve space sample.second.reserve(detections.size()), but this only postpones the error to samples.push_back.

The erroneous line is indicated by the FIXME, causing "terminate called after throwing an instance of 'std::bad_alloc'"

Thanks for any advice in advance.

17
  • 3
    How many times do you loop in your WHILE loop? Are you sure the WHILE loop is not an infinite loop? Commented Oct 26, 2012 at 17:03
  • 1
    I cannot see any error in the code you've posted. Maybe you have heap corruption in getDetections()? Commented Oct 26, 2012 at 17:04
  • In addition to the above, include the definition of the "simple" RotatedRect class in your source. Its copy'ing is directly involved in your loop. Commented Oct 26, 2012 at 17:05
  • 1
    How big can detections.size() get? Commented Oct 26, 2012 at 17:09
  • 1
    @WhozCraig I checked RotatedRect (part of OpenCV) it's just a bunch of floats. No error there. Commented Oct 26, 2012 at 17:13

1 Answer 1

1

std::bad_alloc generally means that you've run out of memory -- possibly because of a leak, or just because you've allocated too much. It can also (rarely) happen due to heap corruption (running off the end of an allocated array or dereferencing a pointer after it has been deleted) or other undefined behavior at some earlier point in the program.

How much memory is your program trying to use at one time? You can try using a leak detector like valgrind to see if there is stuff you should be cleaning up.

edit

The -1 to __builtin_new tells you a lot -- it tells you that someone is calling new with a bogus size. That would probably be a member of std::vector that tries to resize things (you can check the stack trace from valgrind or use a debugger to be sure), which indicates that the vector has been corrupted. Since sample.second is a local (on stack) variable, that tells you that a previous function you called (probably getDetections) overran an onstack buffer or array of some kind and clobbered sample.second. So take a careful look at what that function is doing -- the code you've commented out as //some processing. You can also try using a debugger to set a breakpoint just after sample is created and then set a watchpoint on the memory used by sample.second that is getting corrupted. Then continue the program and it should stop at the point that is clobbering sample.second

It may be helpful to read your compiler's header files to figure out how it implements std::vector -- there's probably a couple of size_t fields and a pointer field in there.

Sign up to request clarification or add additional context in comments.

3 Comments

well, thanks for your suggestion, but valgrind was the first thing I tried. it only prints silly arg (-1) to __builtin_new() and the stacktrace leads to the marked line above
Well this is a clue. operator new expects a size_t. On a 32-bit machine, (size_t)-1 is 4 gigabytes. This explains the std::bad_alloc exception.
Well, @Chris it definitely fails without //some processing in the same way. but I checked out an interesting thing: the debugger tells me that sample.second hast still 0 element although I pushed the first back without an error.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.