Memory
I know that you don’t like these formulas or this pseudocode. It helps a lot though to write out the pseudocode and think about all of the possible outcomes
So we are going to do a little review of memory and offsets in C. There are a fair amount of you which haven’t taken 233 (Which is okay!) but we need to get you up to speed on the prerequisites. So here is a struct.
How we are going to lay this out in memory is with offsets. We will malloc a certain amount of space and each of the variables will take up space right next to each other and take up as much space as the variable is defined to in the standard.
typedef struct{
int n1;
float n2;
char st[10];
} contact;
int main(){
contact bhuvan;
printf("Contact address:\t%p\n", &bhuvan);
printf("Contact n1 location:\t%p\n", &bhuvan.n1);
printf("Contact n2 location:\t%p\n", &bhuvan.n2);
printf("Contact nst location:\t%p\n", &bhuvan.st);
return 0;
}
$ gcc main.c -o stack
$ ./stack
Contact address: 0x7ffcc8568b40
Contact n1 location: 0x7ffcc8568b40
Contact n2 location: 0x7ffcc8568b44
Contact nst location: 0x7ffcc8568b48
GCC or Clang or whatever compiler you use calculates offsets form the base address of your contact (in this case bhuvan). It knows that the first element is at offset 0 and the second element is at offset +4 and the third element is at offset +8 from your starting address.
typedef struct{
int n1;
float n2;
char st[10];
} contact;
int main(){
contact* bhuvan = malloc(sizeof(*bhuvan));
printf("Contact address:\t%p\n", bhuvan);
printf("Contact n1 location:\t%p\n", &bhuvan->n1);
printf("Contact n2 location:\t%p\n", &bhuvan->n2);
printf("Contact nst location:\t%p\n", &bhuvan->st);
free(bhuvan);
return 0;
}
$ gcc malloc-main.c -o malloc-main
$ ./malloc-main
Contact address: 0x1bcd010
Contact n1 location: 0x1bcd010
Contact n2 location: 0x1bcd014
Contact nst location: 0x1bcd018
#include <stdio.h>
#define print_increment(var_name) \
do { \
printf(#var_name "'s address before: %p\n", var_name); \
printf(#var_name "'s address after + 1: %p\n\n", var_name+1); \
} \
while(0)
int main(){
char *char_ptr;
int *int_ptr;
double *double_ptr;
void *void_ptr;
print_increment(char_ptr);
print_increment(int_ptr);
print_increment(double_ptr);
print_increment(void_ptr);
return 0;
}
$ gcc pointer.c -O0 -o pointer
$ ./pointer
char_ptr's address before: 0x400600
char_ptr's address after + 1: 0x400601
int_ptr's address before: 0x400430
int_ptr's address after + 1: 0x400434
double_ptr's address before: 0x7ffe282f0b20
double_ptr's address after + 1: 0x7ffe282f0b28
void_ptr's address before: (nil)
void_ptr's address after + 1: 0x1
Technically yeah, but gcc and clang treats it as a char*. In short, don’t do it because the standard doesn’t gaurentee it.
meta_data *head
: head for linked-listtotal_memory_requested
: keep track of bytes usedtotal_memory_freed
: keep track of bytes freed