Edit : Read this first : https://stackoverflow.com/a/8800541/14795595
I have this code :
#include <assert.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
typedef struct{
double x;
double y;
} point;
point *inserer_point( unsigned *len, point chemin[], point p, unsigned pos ){
assert( pos <= *len );
printf("%d",*len);
if( chemin == NULL )
assert( *len == 0 && pos == 0 );
chemin = realloc( chemin, (*len + 1) * sizeof( point ) );
assert( chemin );
memmove( chemin + pos + 1, chemin + pos, sizeof(point)*( *len - pos ) );
chemin[pos] = p;
(*len)++;
return chemin;
}
int main(){
point *c=NULL;
unsigned l = 0;
c = inserer_point( &l, c, (point){.x = 4, .y = 6}, 0);
c = inserer_point( &l, c, (point){.x = 5, .y = 7}, 0);
c = inserer_point( &l, c, (point){.x = 6, .y = 8}, 2);
c = inserer_point( &l, c, (point){.x = -7, .y = -9}, 1);
c = inserer_point( &l, c, (point){.x = -4, .y = -6}, 4);
c = inserer_point( &l, c, (point){.x = -44, .y = 9}, 4);
c = inserer_point( &l, c, (point){.x = -444, .y = -69}, 2);
}
As you can see, l is declared in main without a malloc, a calloc or a realloc. Which means it is declared in stack. And we don't have control over it.
It should be read only and can only be modified in the context of execution (in the main function).
However, we send a pointer to l in the other function as *len.
And then we increment len (*len++)
at the bottom of the function.
As I said, it should not be possible since it is not on the heap and should be read only.
But this code works and len gets incremented.
Am I wrong about memory access ? What did I not get ? Thank you !
EDIT 2:
This is pretty similar returns SEGMENTATION FAULT. Why ?
void disp (int t[], int a, int b) {
for (int i = a; i < b - 1; i++) {
printf ("%d, ", t[i]);
}
printf("%d\n", t[b - 1]);
}
int *build (int a, int n) {
int t[n];
for (int i = 0; i < n; i++) {
t[i] = a + i;
}
printf ("t : %p : ", t);
disp (t, 0, 15);
return t;
}
int main(void){
printf ("\nbuild tab\n");
int *t = build (0, 15);
printf ("tab : %p\n", t);
disp (t, 0, 15); // SEG_FAULT!
return 0;
}