-1

I'm trying to understand why the following code works in C:

test *liste = NULL;

liste = malloc(sizeof(test)*2);
liste[0].number = 5;
liste[1].number = 10;
liste[2].number = 15;

printf("%d\n", liste[0].number);
printf("%d\n", liste[1].number);
printf("%d\n", liste[2].number);

With the struct being:

typedef struct test {
    int number;
} test;

Output:

5
10
15

I thought, creating only 2 elements of "test" and accessing more than 2 (like here 3) will result in a memory access violation? But why is this working then?

Getting more and more confused here ....

Michael Gierer
  • 401
  • 2
  • 6
  • 15
  • 1
    It's undefined behavior. – klutt May 31 '19 at 20:06
  • You can do whatever you like, until it causes a conflict. There must be a duplicate question which answers this. For example [this one](https://stackoverflow.com/questions/15261472/exceeding-array-bound-in-c-why-does-this-not-crash) and I am sure there are plenty. – Weather Vane May 31 '19 at 20:06
  • 2
    **It does not work!** *not working*, in C, means anthing can happen. This, of course, includes that what the programmer expects (even if she's mistaken) *can* happen (except on Wednesdays, or on full moons, or when the client is watching, ...) – pmg May 31 '19 at 20:06
  • C doesn't mandate bounds checks on array accesses - you've clobbered some memory beyond the end of your allocated object, but that doesn't *have* to result in a runtime error. The behavior on reading/writing memory you don't own is *undefined* - it may result in a runtime error, *or* you may corrupt data, *or* you may leave your program in a bad state such that it crashes later, *or* it may run with no apparent problems. It depends on *what* you overwrite. – John Bode May 31 '19 at 20:07
  • 3
    Welcome to stack overflow! – kpark May 31 '19 at 20:08
  • Here is a more [canonical question](https://stackoverflow.com/questions/15646973/how-dangerous-is-it-to-access-an-array-out-of-bounds). – Weather Vane May 31 '19 at 20:11
  • 1
    It turns out that your question is logically equivalent to: *While driving down the road, I came to a red light. I drove through the intersection anyway. Nothing bad happened. Why not?* – Steve Summit May 31 '19 at 21:37

1 Answers1

3

Welcome to the wonderful world of undefined behavior, where anything can happen!

The C spec says that in certain cases, the result of performing an operation results in what's called undefined behavior. This means that there are no guarantees whatsoever about what might happen when you perform those operations. The program might immediately crash. It might continue to run but with random memory regions corrupted. It might seem to cause no ill effects whatsoever. It might also cause the computer to gain sentience and compose poetry. (That last one is unlikely, but it's technically possible!)

In your case, if you try to access memory that you don't own (here, by reading off the end of a malloc'ed array), the result is undefined behavior. On your system, it seems like walking off by one step in this particular case coincidentally happens to not cause any problems, but walking further than that does lead to a crash. The reason for this likely has to do with the particulars of your memory allocator and the specific machine you're on. This can be jarring if you're coming from a language like Python or Java where errors are more specified and better-defined.

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065