I’ve been doing a bit of testing on some code I wrote when I noticed that I had a huge mistake in my code regarding array sizes, yet the program still ran fine.
Here’s some simplified code to give you an idea of what’s going on.
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int score;
}player;
void printScore(player *p, int num);
int main(void)
{
printf ("\nEnter number of players (1 - 4)\n");
scanf ("%d", &numPlayers);
player *p = (player*)malloc(sizeof(player) * 3);
for (i=0;i<numPlayers;i++)
{
printScore(p, i);
}
}
void printScore(player *p, int num)
{
p[num].score = 1;
printf ("%d\n", p[num].score);
}
The 3 in the malloc function should actually be numPlayers.
If I leave it at 3, and enter a higher number in the menu, the program will usually crash, but it does work sometimes. How is that possible?
If I’ve only enough memory reserved for p[0], p[1], p[2], how does (for example) p[15].score even exist to be populated?
It’s called “undefined behavior”. When the behavior is undefined – everything is possible. Accessing invalid pointer (as in your example) is one of many cases in which the behavior of the program is undefined by the standard, and the compiler is free to do whatever it wishes.
Any behavior is the correct behavior in such case. In your case the compiler just doesn’t do anything, and the program runs as if the memory was allocated. If the OS doesn’t kill you for that (= program crashes on access violation) – that’s your pure luck.