1

In c++ a bad_alloc happen while assigning memory, or at least that was what I understood, but now I get this error while reading memory from an array. I create the array:

int * possible = new int[ suma ];

and then i got two for cycles, where I access the whole array:

for( int i = 0; i < n - 1; i++ ){
    int rowWidth = (i - 1) < 0 ? 0 : permutationsNumber[i];
    for( int j = 0; j < permutationsNumber[i]; j++ ){
        possible[i * rowWidth + j ] = j;
    }
}

for( int i = 0; i < n - 1; i++ ){
    int rowWidth = (i - 1) < 0 ? 0 : permutationsNumber[i];
    for( int j = 0; j < permutationsNumber[i]; j++ ){
        std::cout << possible[i * rowWidth + j ] << "\n";
}

In the second for in the line std::cout << possible[i * rowWidth + j ] << "\n"; is where i got the error.

I compile the code on Windows, tried using 3 different machines with windows 8 and 7, using VS 2010, 2012 and 2013 and got the same error.

When I compile the code on Mac i got no error, same using compileonline

The variable values I didn't think as important are:

n = 4;
permutationsNumber = {4, 12, 24};
suma = 40;
Toxa Kniotee
  • 55
  • 1
  • 7
  • How on earth can we help without knowing the value of `suma`, `i`, `rowWidth` and `j` ? – John3136 Apr 07 '14 at 03:15
  • Are you sure it's a `bad_alloc` exception and not an invalid memory access? Those are different things. Also, what's the value of `suma` when you allocate the `possible` array? – Michael Burr Apr 07 '14 at 03:16
  • `I compile the code on Windows, try using 3 different machines ` So you were expecting to never debug the program?? Once it failed on one machine, it was time to start debugging the program. Second, compiling and running are two different things. A program that compiles ok doesn't mean it will run ok. If it doesn't run ok, then it's time to debug the program. – PaulMcKenzie Apr 07 '14 at 03:16
  • I debug the program, that's why I Know that the error is on the line I said, it tries to access the position 0 of the array when it trows the exception, that's why I don't know what's the problem, also because I already access the whole array with the preview for. Also that's why I didn't put more variable values like suma or the array permutationsNumber – Toxa Kniotee Apr 07 '14 at 03:39

2 Answers2

2

Your understanding of bad_alloc is slightly incorrect. bad_alloc is thrown by the new operator when it fails to allocate the requested amount of memory. It is not uncommon to see this happening if you send extremely large values to new.

For example, this could happen if suma would not be initialized.

You should turn on first-time exception handling in your debugger (catch throw in gdb) and verify where the exception is thrown and what amount of memory your program is requesting.

What you might be observing is an invalid memory reference. You could replace your code to use std::vector and using the at() method to access the elements. This will throw you an exception if you incorrectly access an out-of-range element.

Alternatively, add an assert like this:

#include<cassert>
...
const int idx = i * rowWidth + j;
assert(idx >= 0);
assert(idx < suma);
possible[idx] = j;

If the assertion triggers (it probably will) you will now have confirmed that either your array is too small or your index is invalid.

ppl
  • 1,120
  • 5
  • 18
  • I debug, it pass the `code`int * possible = new int[ suma ];`code` the error is while trying to access the array – Toxa Kniotee Apr 07 '14 at 03:40
  • Also, while debugging checked that the index wasn't incorrect, before the exception throw, the index was 0 – Toxa Kniotee Apr 07 '14 at 03:50
  • I suggest you add the `assert`s to confirm your assumptions. – ppl Apr 07 '14 at 03:52
  • Indeed, `Assertion failed: idx < suma`, which brings other question, how it could pass the first for without Array out of index and why it worked on mac? – Toxa Kniotee Apr 07 '14 at 04:00
  • Because accessing an array with an out of bounds index is undefined behavior, which can manifest itself in any number of ways. – Michael Burr Apr 07 '14 at 04:12
  • As Michael pointed out the behavior is undefined. The reason why it worked in the first place is bad luck. Subtle bugs are harder to find than a blatant crash. – ppl Apr 07 '14 at 04:23
1

You are corrupting your program's heap. The last pass of the first pair of for loops will write to possible[71], but it actually only has 40 slots.

The reason it doesn't necessarily crash immediately is that memory protection typically operates on entire pages (4KB on x86). Unless your buffer happens to fall right at the end of the page, chances are many locations past the end of the array will fall on the same (valid) page as the end of the array, so writing to them may not cause an immediate fault.

On Windows, you can use the gflags utility to force all heap allocations to end at the end of a page, so that overruns will cause an immediate page fault.

nobody
  • 19,814
  • 17
  • 56
  • 77