1

I was bored and wanted to make a program to crash my computer :P. I would have it uselessly and redundantly allocate memory until the crash. The code I created so far is here:

#include <cstdlib>
#include <cstdio>

int main(int argc, const char *argv)
{
    int n = 0;
    while (1)
    {
        n++;
        int* buffer = (int*)malloc(n ^ n);
        int* buffer_buffer = (int*)calloc(n, sizeof(buffer));
        for (int i = 0; i < n; i++) {
            printf("%p", &buffer);
            printf("\n");
            buffer_buffer[i] = (int)buffer;
        }
    }
}

The code works(it crashes the computer), but does not work as expected.I wanted to go more into the process of the how it worked and what exactly it was doing, so I set a few breakpoints and decided to step through it. I expected to see the buffer_buffer reallocated again and again containing n numbers of buffer, but it does not. Instead, my debugger shows that buffer_buffer contains a single value that sometimes will change, and a single value(the integer cast of buffer at least I hope) is logged every go round the loop. I was expecting the buffer_buffer to grow with n number of elements every time around the for loop comes around, but it only has one element. To visualize this, here is a screenshot of the debugger:

Debugger

Again I am somewhat tired and this is probably an issue with my loop logic. Does anyone know why my program is experiencing this unexpected behavior? I am using the Microsoft Visual Studio debugger

genpfault
  • 51,148
  • 11
  • 85
  • 139
James Parsons
  • 6,097
  • 12
  • 68
  • 108
  • 4
    Sidenote: `^` is bitwise xor, so `malloc(n ^ n)` will allocate zero bytes of memory. – sth May 29 '15 at 01:48
  • @sth technically it will *request* zero bytes; the implementation may either return a null pointer, or a non-null pointer which you aren't permitted to dereference. Some implementations might allocate memory anyway. – M.M May 29 '15 at 02:39
  • 1
    it's also unclear what you expect the body of the inner loop to do. `buffer` is never modified during this loop so `&buffer` and `(int)buffer` are the same every time you check them. – M.M May 29 '15 at 02:41

1 Answers1

4

Probably your debugger doesn't know how big buffer_buffer is, since that variable is simply declared as being a pointer to an int. (That's not correctly typed; buffer_buffer is used to hold values of buffer which is an int*, so buffer_buffer must be an array of int*, which means that you should declare it as int**, i.e. a pointer to a sequence of int*.) One of the little challenges in debugging C programs is that the length of an array is not stored anywhere at all; you have to keep track of it yourself. So the debugger doesn't know either.

Also, n^n is 0, since ^ is the XOR operator. I don't know if that is what you intended.


(Actually, it's not quite true that the allocation size isn't stored anywhere. It might be, or some approximation to it might be. But it's stored in the internals of the memory allocation library, and there is no way to get at it. And anyway, it might not be correct, because the library sometimes allocates more than you asked for, and it only remembers what it allocated, not what you asked for.)

rici
  • 234,347
  • 28
  • 237
  • 341
  • Whoops I saw something about `int**` once and had no idea what that was. As for the `^` I must have got mixed up. I was meaning to use exponentiation. – James Parsons May 29 '15 at 01:48
  • Also, would using a lower level debugger(at the asm or binary level) help with the debugger issue? – James Parsons May 29 '15 at 01:49
  • 1
    @James_Parsons You can type, `buffer_buffer,n` in the watch window to see the full contents if you're using MSVC (it looks from your screenshot like it's MSVC, can't tell for sure). Other debuggers might accept that format as well. –  May 29 '15 at 01:52
  • 1
    @James_Parsons: No. There is really no way to figure out how long the allocation is. Your program is expected to know. (And it does -- the array has `n` elements.) By the way, you know that you are allocating a new larger `buffer_buffer` every time through that loop, but never freeing the old ones, and then only setting one element in the new one? Perhaps you meant `realloc`, not `calloc`? – rici May 29 '15 at 01:53
  • Oops yeah its MSVC should have specified that. – James Parsons May 29 '15 at 01:53
  • 1
    @James_Parsons: Also, C doesn't have an exponentiation operator. You can use the `pow` math library function, but because that function uses floating point and does not guarantee perfect accuracy, it's possible that truncating it back to an integer will result in a value one less than you expect. – rici May 29 '15 at 01:56
  • "the length of an array is not stored anywhere at all; you have to keep track of it yourself." - it should be clarified that this only refers to arrays allocated via `malloc` and friends. The length of named arrays is available via the array's name at any time. – M.M May 29 '15 at 02:40