I'm in the process of learning how to use pointers and structs in C. Naturally, I'm trying to deliberately break my code to further understand how the language works. Here is some test code that works as I expected it to work:
#include <stdio.h>
#include <stdlib.h>
struct pair {
int x;
int y;
};
typedef struct pair pair;
void p_struct( pair ); //prototype
int main( int argc, char** argv ) {
pair *s_pair;
int size, i;
printf( "Enter the number of pair to make: " );
scanf( "%d", &size );
getchar();
printf( "\n" );
s_pair = (pair*)malloc( size * sizeof(pair) );
for( i = 0; i < size; i++ ) {
s_pair[i].x = i;
s_pair[i].y = i;
p_struct( s_pair[i] );
}
getchar();
return (EXIT_SUCCESS);
}
void p_struct( pair s_pair ) {
printf( "\n%d %d\n", s_pair.x, s_pair.y );
}
As previously stated, this code is functional as far as I can tell.
I then decided to modify a part of the code like so:
for( i = 0; i < size + 3; i++ ) {
s_pair[i].x = i;
s_pair[i].y = i;
p_struct( s_pair[i] );
}
This modification did not produce the seg fault error that I expected it would. All of the "pairs" were printed despite me exceeding the buffer I explicitly set when assigning a value to my variable size using the scanf function.
As I understand pointers (correct me if I'm wrong), a contiguous block of memory of size size*sizeof(pair) is reserved by the memory manager in the heap when I called the malloc function for my pointer of type pair s_pair. What I did was I exceeded the last assigned address of memory when I modified my for loop to the condition i < size + 3.
If I'm understanding this correctly, did my pointer exceed its reserved memory limit and just so happen to be in the clear because nothing adjacent and to the right of it was occupied by other data? Is this normal behaviour when overflowing a buffer?
To add, I did receive a seg fault when I tested with a for loop condition of i < size + 15. The thing is, it still prints the output. As in, it prints the pair "0 0" to pair "24 24" when size = 10 on the screen as per the p_struct function I made. The program crashes by seg fault only after it gets to one of those getchar()s at the bottom. How on earth could my program assign values to pairs that exceed the buffer, print them on the screen, and then all of a sudden decide to crash on seg fault when it gets to getchar()? It seemed to have no issue with i < size + 3 (despite it still being wrong).
For the record, I also tested this behaviour with a regular pointer array:
int size, i, *ptr;
scanf( "%d", &size );
ptr = (int*)malloc( size * sizeof(int) );
for( i = 0; i < size + 15; i++ )
ptr[i] = i;
This produces the exact same result as above. At i < size + 3 there doesn't seem to be any issue with seg faults.
Finally, I tested with an array, too:
int i, array[10];
for( i = 0; i < 25; i++ )
array[i] = i;
For the condition i < 25, I get a seg fault without fail. When I change it to i < 15, I receive no seg fault.
If I remember correctly, the only difference between an array of pointers and an array is that the memory allocated to an array is located on the stack as opposed to the heap (not sure about this). With that in mind, and considering the fact that i < 15 when array[10] doesn't produce any seg faults, why would i < 25 be an issue? Isn't the array at the top of the stack during that for loop? Why would it care about 100 extra bytes when it didn't care about 60 extra bytes? Why isn't the ceiling for that array buffer all the way to the end of whatever arbitrary chunk of memory is reserved for the whole stack?
Hopefully all of this made sense to whoever decides to read a slightly inebriated man's ramblings.