/* This is a collection of functions we are writing to develop a deeper understanding of how memory is managed in C. * * We learned that C has a strategy for allocating memory that * allocates memory of different chunk sizes in different areas. * This is a strategy that prevent the heap from being segmented * locally. */ #include #include #include #include // where are arrays placed? // on the stack. // only malloc allocates memory on the heap void test1( int N ) { int a[4]; // should be on stack int b[N]; // this is on the stack // scary example int M; int d[M]; // yikes!!! How big is this? M doesn't have a value. int *c = (int *)malloc( sizeof(int)*4 ); // should be on heap printf( "address of a is %p\n", &a ); printf( "address of b is %p\n", &b ); printf( "address of d is %p\n", &d ); printf( "address of M is %p and its value is %d\n", &M, M ); printf( "address of c is %p and it points to %p\n", &c, c ); M = 2; } // Is freed memory reused? void test2() {; int *a; int i; for (i = 0; i < 4; i++) { a = (int *)malloc( sizeof(int) * 12 ); printf( "a points to address %p\n", a ); free( a ); } } // Are memory chunks of the same size allocated contiguously? void test3() {; int *a; int i; for (i = 0; i < 4; i++) { a = (int *)malloc( sizeof(int) * 12 ); printf( "a points to address %p\n", a ); // free( a ); } } // Are memory chunks of different sizes allocated contiguously? void test4() {; int *a; int i; for (i = 0; i < 4; i++) { a = (int *)malloc( sizeof(int) * (i+20) ); printf( "a points to address %p\n", a ); // free( a ); } } // Are memory chunks of particular size ranges allocated together // on the heap? void test5() { int *a; int i; for (i = 0; i < 4; i++) { printf( "allocating chunks of size %lu\n", sizeof(int) * (size_t)pow(10,i+1) ); for (int j = 0; j < 4; j++) { a = (int *)malloc( sizeof(int) * (size_t)pow(10,i+1)); printf( "a points to address %p\n", a ); // free( a ); } } } // Can I determine how the sizes are split up in the heap? // For sizes increasing by 1 byte at a time, the chunk size incremented by 16 bytes. // this was from 1 byte to 1024 bytes // From 100 bytes to 102,400 bytes, most allocations are 512 bytes, then it jumps to 32,768 (we don't know the size // for the last one because we didn't allocate something after it) void test6() { char *addresses[1024]; unsigned long need_szs[1024]; unsigned long sort_of_have_szs[1023]; for (int i = 0; i < 1024; i++) { unsigned long sz = (i+1)*100; char *ptr = (char *)malloc( sz ); addresses[i] = ptr; need_szs[i] = sz; if (i >= 1) { sort_of_have_szs[i-1] = addresses[i]-addresses[i-1]; // we got at least this much, assuming there wasn't a big jump in location } } for (int i = 0; i < 1023; i++) { printf( "When we need %lu, we maybe get %lu\n", need_szs[i], sort_of_have_szs[i] ); } } int main(int argc, char *argv[]) { // test1(8); // test1(8); // test2(); // test3(); // test4(); // test5(); test6(); }