tags:

views:

97

answers:

5
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int *numeros = malloc(sizeof(int) * 3 * 3);
    numeros[900] = 10;
    printf("%d", numeros[900]);
    free(numeros);
    return 0;
}

Why exactly this prints out 10 when I haven't allocated enough memory? I'm pretty sure I'm missing something big on pointers/etc.

Thanks for helping out

+14  A: 

What you observe is undefined behavior - you write outside the allocated buffer and likely overwrite some memory that happens to be mapped into the process.

Depending on various factors this might crash your program or just do nothing or corrupt data in the program. Don't do it, only access memory that you've legally allocated.

Also see this related question.

sharptooth
*Half kidding* it might also write that `10` in some part of the Operating System and , because of that, format your hard drive :-)
pmg
@pmg: Yeap, or send all your passwords over the network - similar to this UB instance http://stackoverflow.com/questions/908872/whats-the-worst-example-of-undefined-behaviour-actually-possible/3554343#3554343
sharptooth
+1  A: 

Your array size is 9. So when you try to access a memory location 900 which is out of bounds.

Your behavior is undefined. Meaning, sometimes it could print junk values, sometimes it could crash. So always initialize your vars before usage.

MovieYoda
+1  A: 

What you're missing is that the compiler isn't required to catch this case, and often won't. This is undefined behavior, which means that there are no requirements as to what the implementation does, and it's your job to avoid it. Typically, the compiler will just compile whatever it sees in case of undefined behavior, and the sometimes reasonable behavior that comes out can be confusing.

In this case, you stored a memory address in numeros, and in the next statement referenced *(numeros + 900), which given the usual int size would be 3600 bytes after the memory address. The compiler generated the code for the reference. Considering that this is undefined behavior, the compiler was perfectly correct to do so, or for that matter to write an insulting email to you or your mother; the Standard specifies nothing. It could, of course, detect this and give you a run-time error saying "Address out of bounds at line 7", but unfortunately none of the compilers I've used give you that option.

This is one of the trickier parts of C programming: making sure your program is well-defined.

David Thornley
+1: your post reminded me of something I read somewhere: **C compilers trust the programmer.** Lie to the compiler and it'll get its revenge
pmg
A: 

You Allocated memory for 9 elements with malloc:

 int *numeros = malloc(sizeof(int) * 3 * 3); 
        // allocates memory of (4) *(9) bytes==36 bytes

Now your array bounds should be within the limit of int's for which you allocated memory which is the number by which you multiplied your sizeof(int).It allocated memory for for as much int's.

fahad
A: 

You're able to do this because you've allocated your array from the heap, which is probably at least 32K. So what you're doing is writing to some other location in the heap, which is "legal". If you bumped your array index up to 128000 or so, you might get an access violation. As it is, you're (potentially) overwriting some other data you've allocated, or possibly the actual heap management metadata (block headers).

TMN