Created
March 19, 2012 18:03
-
-
Save erikkaplun/2121953 to your computer and use it in GitHub Desktop.
smartpointer (C)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <assert.h> | |
#define DEBUG | |
#include "smartasspointer.h" | |
struct spaceship_t { /* extends */ smartass_t _; | |
const char* name; | |
}; | |
spaceship_t* spaceship_new(const char *name) | |
{ | |
LOG("spaceship_new"); | |
spaceship_t* self = (spaceship_t*) malloc(sizeof(spaceship_t)); | |
smartass_init((smartass_t*) self); | |
self->name = name; | |
return self; | |
} | |
void spaceship_delete(spaceship_t** self) | |
{ | |
LOG("spaceship_delete"); | |
smartass_cleanup((smartass_t*) *self); | |
free(*self); | |
*self = NULL; | |
} | |
typedef struct { | |
spaceship_t* spaceship; | |
} missile_t; | |
missile_t* missile_new(spaceship_t* spaceship) | |
{ | |
LOG("missile_new"); | |
missile_t* self = (missile_t*) malloc(sizeof(missile_t)); | |
point((void**) &(self->spaceship), spaceship); | |
return self; | |
} | |
void missile_delete(missile_t** self) | |
{ | |
LOG("missile_delete"); | |
unpoint((void**) &((*self)->spaceship)); | |
free(*self); | |
*self = NULL; | |
} | |
int main() | |
{ | |
spaceship_t* ss1 = spaceship_new("Spaceship 1"); | |
missile_t* missile1 = missile_new(ss1); | |
missile_t* missile2 = missile_new(ss1); | |
missile_t* missile3 = missile_new(ss1); | |
spaceship_delete(&ss1); | |
assert(missile1->spaceship == NULL); | |
assert(missile2->spaceship == NULL); | |
assert(missile3->spaceship == NULL); | |
spaceship_t* ss2; | |
point((void**) &ss2, spaceship_new("Spaceship 2")); | |
missile_t* missile11 = missile_new(ss2); | |
missile_t* missile12 = missile_new(ss2); | |
missile_t* missile13 = missile_new(ss2); | |
missile_t* missile14 = missile_new(ss2); | |
missile_t* missile15 = missile_new(ss2); | |
unpoint((void**) &ss2); | |
missile_delete(&missile11); | |
missile_delete(&missile12); | |
missile_delete(&missile13); | |
missile_delete(&missile14); | |
spaceship_t* ss2_ptr; | |
point((void**) &ss2_ptr, missile15->spaceship); | |
missile_delete(&missile15); | |
unpoint((void**) &ss2_ptr); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <assert.h> | |
#define DEBUG | |
#include "smartasspointer.h" | |
#define MAGIC_NR 100 | |
void smartass_init(smartass_t* self) | |
{ | |
LOG("smartass_init"); | |
self->numptrs = 0; | |
self->ptrs = (void***) malloc(MAGIC_NR * sizeof(void**)); // fuck it | |
self->tail = self->ptrs; | |
} | |
void smartass_cleanup(smartass_t* self) | |
{ | |
LOG("smartass_cleanup"); | |
for (uint i = 0; i < MAGIC_NR; i += 1) { | |
if (self->ptrs[i] != NULL) { | |
LOG("found pointer to smartass"); | |
*self->ptrs[i] = NULL; | |
self->ptrs[i] = NULL; | |
} | |
} | |
} | |
void point(void** ptr, void* obj) | |
{ | |
LOG("point"); | |
smartass_t* smartass = (smartass_t*) obj; | |
*(smartass->tail) = ptr; | |
*ptr = obj; | |
smartass->tail += 1; | |
smartass->numptrs += 1; | |
} | |
void unpoint(void** ptr) | |
{ | |
LOG("unpoint"); | |
smartass_t* smartass = (smartass_t*) *ptr; | |
int found = 0; | |
for (int i = 0; i < MAGIC_NR; i += 1) { | |
if (smartass->ptrs[i] == ptr) { | |
smartass->ptrs[i] = NULL; | |
smartass->numptrs -= 1; | |
found = 1; | |
LOG("removing pointer to smartass"); | |
break; | |
} | |
} | |
assert(found == 1); | |
if (smartass->numptrs == 0) { | |
LOG("setting smartass free"); | |
free(smartass); | |
} | |
*ptr = NULL; | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef __SMARTASSPOINTER_H__ | |
#define __SMARTASSPOINTER_H__ | |
typedef unsigned int uint; | |
#ifdef DEBUG | |
#define IS_DEBUG 1 | |
#else | |
#define IS_DEBUG 0 | |
#endif | |
#define LOG(x) if (IS_DEBUG) { puts(x); } | |
typedef struct { | |
uint numptrs; | |
void*** tail; | |
void*** ptrs; | |
} smartass_t; | |
void smartass_init(smartass_t* self); | |
void smartass_cleanup(smartass_t* self); | |
void point(void** ptr, void* obj); | |
void unpoint(void** ptr); | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment