I ran the following C code on Linux (Ubuntu-22.04 x86-64):
#include <malloc.h>
#include <unistd.h>
int main() {
char* s = malloc(8 * 1024 * sizeof(char));
for (int i = 0; i < 10 * 1024; ++i) { // out-of-bound access
s[i] = i; // Write to s
}
usleep(1); // To bring possible access to s, or the compiler may optimize out s
free(s); // Crash
}
But the program doesn't crash at the assignment s[i] = i
but crash at free(s)
:
double free or corruption (!prev)
However, if I read from s instead of write to s, no error will occur:
#include <malloc.h>
#include <stdio.h>
#include <unistd.h>
int main() {
char* s = malloc(8 * 1024 * sizeof(char));
for (int i = 0; i < 10 * 1024; ++i) {
printf("%d\n", (int)s[i]); // Read from s
}
usleep(1);
free(s); // No errors
}
Furthermore, on Windows it crashes just at the assignment s[i] = i;
, which is much more easier to understand (page fault).
Then how Linux implement free
? What does the program do inside the function free
?
Diff view on compiler explorer: