Fix all memory leaks

This commit is contained in:
olemorud
2023-04-24 23:44:17 +02:00
parent 3b7cc458fc
commit 2eeaa2171f
4 changed files with 69 additions and 20 deletions

View File

@@ -4,7 +4,7 @@
#include <stdbool.h> // bool
#define OBJ_SIZE 64
#define OBJ_SIZE 32
typedef struct obj_entry {
char const* key;
@@ -25,7 +25,7 @@ struct json_value {
enum json_type type;
union {
obj_t* object;
struct json_value** array;
struct json_value** array; // we need an array of pointers to allow null termination
char* string;
bool boolean;
double number;
@@ -34,8 +34,10 @@ struct json_value {
void* obj_at(obj_t m, char* const key);
bool obj_insert(obj_t m, char* const key, struct json_value* value);
void obj_delete(obj_t m);
void obj_delete(obj_t* m);
void print_json(struct json_value val, int indent);
void json_value_delete(struct json_value val);
#endif

View File

@@ -10,11 +10,12 @@
bool obj_insert(obj_t m, char* const key, struct json_value* value);
size_t obj_hash(char const* str);
void obj_delete(obj_t m);
void obj_delete(obj_t* m);
void* obj_at(obj_t m, char* const key);
void print_array(struct json_value** arr, int cur_indent, int indent_amount);
void print_json_value(struct json_value val, int cur_indent, int indent_amount);
void print_object(obj_t obj, int cur_indent, int indent_amount);
void* obj_at(obj_t m, char* const key);
/*
djb2 string hash
@@ -104,7 +105,7 @@ bool obj_insert(obj_t m, char* const key, struct json_value* value)
/* populate new entry */
cur = malloc_or_die(sizeof(struct obj_entry));
cur->key = strdup(key);
cur->key = key;
cur->val = value;
cur->next = m[i];
@@ -114,27 +115,52 @@ bool obj_insert(obj_t m, char* const key, struct json_value* value)
return true;
}
void json_value_delete(struct json_value val)
{
switch (val.type) {
case array:
for (size_t i = 0; val.array[i] != NULL; i++) {
json_value_delete(*(val.array[i]));
free(val.array[i]);
}
free(val.array);
break;
case object:
obj_delete(val.object);
break;
case string:
free(val.string);
break;
default:
break;
}
}
/*
Free memory allocated for obj
TODO: recurively delete children objects
*/
void obj_delete(obj_t m)
void obj_delete(obj_t* m)
{
for (size_t i = 0; i < OBJ_SIZE; i++) {
if (m[i] == NULL)
continue;
struct obj_entry *e = m[i], *tmp;
struct obj_entry *e = (*m)[i], *tmp;
while (e != NULL) {
tmp = e;
json_value_delete(*(e->val));
free((char*)e->key);
free(e->val);
tmp = e;
e = e->next;
free(tmp);
}
}
free(m);
}
void add_indent(int n)

View File

@@ -16,9 +16,13 @@ int main(int argc, char* argv[])
FILE* fp = fopen(argv[1], "r");
volatile struct json_value x = parse_json_value(fp);
struct json_value x = parse_json_value(fp);
print_json(x, 1);
// print_json(x, 1);
json_value_delete(x);
fclose(fp);
return EXIT_SUCCESS;
}

View File

@@ -113,7 +113,7 @@ struct json_value parse_json_value(FILE* fp)
char* read_string(FILE* fp)
{
int c;
size_t i = 0, result_size = 16 * sizeof(char);
size_t i = 0, result_size = 16;
char* result = malloc_or_die(result_size);
bool escaped = false;
@@ -141,6 +141,7 @@ char* read_string(FILE* fp)
return realloc_or_die(result, i);
case EOF:
free(result);
err_ctx(EARLY_EOF, fp, "(%s) unexpected EOF", __func__);
default:
@@ -170,9 +171,11 @@ obj_t* read_object(FILE* fp)
switch (fgetc(fp)) {
case EOF:
free(result);
err_ctx(EARLY_EOF, fp, "(%s) unexpected EOF", __func__);
default:
free(result);
err_ctx(UNEXPECTED_CHAR, fp, "(%s) expected \"", __func__);
case '"':
@@ -191,9 +194,11 @@ obj_t* read_object(FILE* fp)
break;
case EOF:
free(result);
err_ctx(EARLY_EOF, fp, "(%s) unexpected EOF", __func__);
default:
free(result);
err_ctx(UNEXPECTED_CHAR, fp, "(%s) expected ':'", __func__);
}
@@ -204,14 +209,19 @@ obj_t* read_object(FILE* fp)
*val = parse_json_value(fp);
/* insert key-value pair to obj */
if (!obj_insert(*result, key, val))
if (!obj_insert(*result, key, val)) {
free(result);
free(val);
errx(EXIT_FAILURE, "failed to insert pair (%s, %p)", key, (void*)val);
}
/* read separator or end of object */
discard_whitespace(fp);
switch (fgetc(fp)) {
case EOF:
free(val);
free(result);
err_ctx(EARLY_EOF, fp, "(%s) unexpected EOF", __func__);
case ',':
@@ -221,6 +231,8 @@ obj_t* read_object(FILE* fp)
return result;
default:
free(val);
free(result);
err_ctx(UNEXPECTED_CHAR, fp, "(%s) expected ',' or '}'", __func__);
}
}
@@ -252,6 +264,11 @@ struct json_value** read_array(FILE* fp)
switch (c) {
case EOF:
free(output);
for (size_t j = 0; j < i; j++)
free(output[j]);
err_ctx(EARLY_EOF, fp, "(%s) unexpected EOF", __func__);
break;
@@ -281,7 +298,7 @@ struct json_value** read_array(FILE* fp)
void read_null(FILE* fp)
{
static const char ok[] = { 'n', 'u', 'l', 'l' };
char buf[sizeof(ok)];
static char buf[sizeof(ok)];
size_t n_read = fread(buf, sizeof(char), sizeof(ok), fp);
@@ -304,7 +321,7 @@ bool read_boolean(FILE* fp)
static const char t[] = { 't', 'r', 'u', 'e' };
static const char f[] = { 'f', 'a', 'l', 's', 'e' };
char buf[sizeof(f)] = { 0 };
static char buf[sizeof(f)] = { 0 };
size_t n_read = fread(buf, sizeof(char), sizeof(f), fp);