Skip to content

Instantly share code, notes, and snippets.

@JZHeadley
Last active October 23, 2016 03:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JZHeadley/c5f614ba9c3182775372418fc428b91d to your computer and use it in GitHub Desktop.
Save JZHeadley/c5f614ba9c3182775372418fc428b91d to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include "malloc-support.h"
int main() {
int *ptr = malloc(sizeof(int));
if (ptr == NULL) {
printf("couldn't malloc an int");
return 1;
}
*ptr = 1;
*ptr = 100;
free(ptr);
printf("freed the int after assigning it a value");
return 0;
}
INCLUDES=-I.
CC=gcc
CFLAGS=-I. -c -g -Wall $(INCLUDES)
FLAGS = -O0 -W -Wall -Wextra -g
LINKARGS=-lm
LIBS=-lm
# Productions
all : assign2
assign2 : assign2.o malloc.so
$(CC) $(LINKARGS) $^ -o $@ $(LIBS)
malloc.so: malloc-support.c malloc-support.h
$(CC) $^ $(FLAGS) -o $@ -shared -fPIC
assign2.o : assign2.c malloc-support.h
$(CC) $< $(CFLAGS) -o $@
clean :
rm -f malloc.so assign2.o assign2
run :
valgrind ./assign2
#include "malloc-support.h"
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#define META_SIZE sizeof(struct block_meta)
void *global_base = NULL;
void *nofree_malloc(size_t size) {
void *p = sbrk(0);
void *request = sbrk(size);
if (request == (void *) -1) {
return NULL; // sbrk failed
} else {
assert(p == request); // Not thread safe.
return p;
}
}
struct block_meta {
size_t size;
struct block_meta *next;
int free;
int magic; // For debugging only. TODO: remove this in non-debug mode.
};
// Iterate through blocks until we find one that's large enough.
// TODO: split block up if it's larger than necessary
struct block_meta *find_free_block(struct block_meta **last, size_t size) {
struct block_meta *current = global_base;
while (current && !(current->free && current->size >= size)) {
*last = current;
current = current->next;
}
return current;
}
struct block_meta *request_space(struct block_meta *last, size_t size) {
struct block_meta *block;
block = sbrk(0);
void *request = sbrk(size + META_SIZE);
assert((void * ) block == request); // Not thread safe.
if (request == (void *) -1) {
return NULL; // sbrk failed.
}
if (last) // NULL on first request.
{
last->next = block;
}
block->size = size;
block->next = NULL;
block->free = 0;
block->magic = 0x12345678;
return block;
}
void *malloc(size_t size) {
struct block_meta *block;
if (size <= 0) {
return NULL;
}
if (!global_base) {
block = request_space(NULL, size);
if (!block) {
return NULL;
}
global_base = block;
} else {
struct block_meta *last = global_base;
block = find_free_block(&last, size);
if (!block) // Failed to find free block.
{
block = request_space(last, size);
if (!block) {
return NULL;
}
} else // Found free block
{
// TODO: consider splitting block here.
block->free = 0;
block->magic = 0x77777777;
}
}
return (block + 1);
}
void *calloc(size_t nelem, size_t elsize) {
size_t size = nelem * elsize; // TODO: Check for overflow
void *ptr = malloc(size);
memset(ptr, 0, size);
return ptr;
}
struct block_meta *get_block_ptr(void *ptr) {
return (struct block_meta *) ptr - 1;
}
;
void free(void *ptr) {
if (!ptr) {
return;
}
// TODO: consider merging blocks once splitting blocks is implemented.
struct block_meta *block_ptr = get_block_ptr(ptr);
assert(block_ptr->free == 0);
assert(block_ptr->magic == 0x77777777 || block_ptr->magic == 0x12345678);
block_ptr->free = 1;
block_ptr->magic = 0x55555555;
}
void *realloc(void *ptr, size_t size) {
if (!ptr) {
// NULL ptr. realloc should act like malloc.
return malloc(size);
}
struct block_meta *block_ptr = get_block_ptr(ptr);
if (block_ptr->size >= size) {
return ptr;
}
void *new_ptr;
new_ptr = malloc(size);
if (!new_ptr) {
return NULL;
}
memcpy(new_ptr, ptr, block_ptr->size);
free(ptr);
return new_ptr;
}
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#ifndef MALLOC_SUPPORT_H_
#define MALLOC_SUPPORT_H_
struct block_meta;
struct block_meta *find_free_block(struct block_meta **last, size_t size);
struct block_meta *request_space(struct block_meta *last, size_t size);
struct block_meta *get_block_ptr(void *ptr);
void *nofree_malloc(size_t size);
void *malloc(size_t size);
void *calloc(size_t nelem, size_t elsize);
void free(void *ptr);
void *realloc(void *ptr, size_t size);
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment