1

I need to test the performance of my project on Windows.
I have an array of arrays rede_conexoes, and allocate each position in a loop, but after some iterations the malloc function doesn't work and abruptly stops my process, before I can even test the return value and shows no error message.

The code works perfectly fine on the WSL (Windows Subsystem for Linux) on Windows 10. To test the code natively on Windows, I installed Mingw-w64 for the gcc compiler (couldn't find a better solution, as support for OpenMP is needed).
Here is the snippet with the malloc function:

bool **rede_conexoes = (bool**) malloc(num_PL * sizeof(bool*));
...
for(int i = 0; i < num_PL; i++){
    rede_conexoes[i] = (bool*)malloc(num_PL*sizeof(bool)); // <- Error occurs here
    if(rede_conexoes[i] == NULL) exit(1); // <- Can't get to this line after the error
    for(int j = 0; j < num_PL; j++)
        fscanf(model, "%d", (int*)&rede_conexoes[i][j]);
}

I don't understand how can this run with no issues on WSL but on Windows it crashes and there is no error message.
I noticed that it starts to fail when num_PL is greater than 2^3 = 8, there's no problem if num_PL is greater than 2^15 = 32768 on Linux. I tested the .exe created by gcc on Command Prompt(cmd) and PowerShell, both with the same results.

  • does the file have enough numbers? – Gerardo Zinno Jun 06 '19 at 01:17
  • 1
    BTW, it's better if you [don't cast the result of malloc] (https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – Gerardo Zinno Jun 06 '19 at 01:21
  • `fscanf(model, "%d", (int*)&rede_conexoes[i][j]);` writes out of bounds if `sizeof(bool) < sizeof(int)` (which is true on many implementations) and also may create trap representations. And the pointer might be incorrectly aligned for `int`. You should read into an `int` variable and then assign to the array location – M.M Jun 06 '19 at 01:29
  • That `fscanf()` is badly broken; you're telling it a pointer to a `_Bool` is a pointer to an `int`. Hello undefined behavior. – Shawn Jun 06 '19 at 01:30
  • 1
    Also you should post a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) as the problem might be heap corruption elsewhere in your program and happen to show up at this point – M.M Jun 06 '19 at 01:30
  • @Shawn it's actually writing into `malloc`'d space so that is not a problem per se (but undefined behaviour would occur at the very end when it overflows the allocation, and it might write an invalid bit pattern for a Bool which would cause UB later when the bool is read) – M.M Jun 06 '19 at 01:32

2 Answers2

3

When you read the last number (when i == num_PL - 1 and j == num_PL - 1) into &rede_conexoes[i][j], you've allocated space for a bool (typically 1 byte), but you've asked the runtime to read in an int (commonly 4 or sometimes 8 bytes). This will potentially write a few bytes past the end of the space you've allocated. This results in Undefined Behavior, resulting in the program appearing to work, misbehaving, or crashing.

Depending on the value of num_PL and how your runtime handles memory management, these extra few bytes can overwrite some of the control data used by the runtime to track memory blocks. Depending on what's been overwritten and how it is used, this can lead to the crash you're getting.

One solution, as mentioned in the comments, would be to read the integer into a local variable of type int, then assign that to your bool array.

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
  • Changed the `fscanf` to store it on a temporary variable and later assigned it to `rede_conexoes[i][j]` and it solved the problem! I tested the sizes of `bool`, `bool*`, `int` and `int*`, the pointers use 8 bytes on Linux but 4 on Windows, whitch may be the cause of the Undefined Behavior. – Tobias A. G. Jun 06 '19 at 15:11
0

Maybe, the calling proccess are not allowed by the OS to give you all that memory.

Assuming you are working with a quadratic bidimensional (2D) array:

2^15 * 2^15 = 32.768 * 32.768 = 1.073.741.824 booleans!

If you are running this code in a 32bit architecture sizeof(bool*) = 4:

1.073.741.824 * 4 = 4.294.967.296 (4GB)

If you are running this code in a 64bit architecture sizeof(bool*) = 8:

1.073.741.824 * 8 = 8.589.934.592 (8GB)

All that memory are available to the calling proccess ?

Lacobus
  • 1,590
  • 12
  • 20