fixes memory leak in free struct

This commit is contained in:
overflowerror 2021-05-04 17:07:20 +02:00
parent 91d0dce081
commit fcf69c17c8
3 changed files with 26 additions and 12 deletions

View file

@ -20,7 +20,7 @@ static struct marshaller {
const char* name; const char* name;
jsonValue_t* (*marshaller)(void*); jsonValue_t* (*marshaller)(void*);
void* (*unmarshaller)(jsonValue_t*); void* (*unmarshaller)(jsonValue_t*);
void (*free)(void*); void (*free)(void*, bool);
}* marshallerList = NULL; }* marshallerList = NULL;
static size_t marshallerListLength = 0; static size_t marshallerListLength = 0;
@ -34,7 +34,7 @@ static struct marshaller* findMarshaller(const char* type) {
return NULL; return NULL;
} }
void _registerMarshaller(int namesCount, const char** names, jsonValue_t* (*marshaller)(void*), void* (*unmarshaller)(jsonValue_t*), void (*structFree)(void*)) { void _registerMarshaller(int namesCount, const char** names, jsonValue_t* (*marshaller)(void*), void* (*unmarshaller)(jsonValue_t*), void (*structFree)(void*, bool)) {
marshallerList = realloc(marshallerList, (sizeof(struct marshaller)) * (marshallerListLength + namesCount)); marshallerList = realloc(marshallerList, (sizeof(struct marshaller)) * (marshallerListLength + namesCount));
if (marshallerList == NULL) { if (marshallerList == NULL) {
_marshallPanic(names[0], NULL); _marshallPanic(names[0], NULL);
@ -282,7 +282,7 @@ void* _json_unmarshall(const char* type, const char* json) {
return tmp; return tmp;
} }
void _json_free_struct(const char* type, void* value) { void _json_free_struct(const char* type, void* value, bool this) {
if (value == NULL) { if (value == NULL) {
return; return;
} else if (strcmp(type, "char") == 0 || } else if (strcmp(type, "char") == 0 ||
@ -295,12 +295,13 @@ void _json_free_struct(const char* type, void* value) {
strcmp(type, "bool") == 0 || strcmp(type, "bool") == 0 ||
strcmp(type, "string") == 0 strcmp(type, "string") == 0
) { ) {
free(value); if (this)
free(value);
} else { } else {
struct marshaller* marshaller = findMarshaller(type); struct marshaller* marshaller = findMarshaller(type);
if (marshaller == NULL) { if (marshaller == NULL) {
_marshallPanic(type, "unknown type"); _marshallPanic(type, "unknown type");
} }
marshaller->free(value); marshaller->free(value, this);
} }
} }

View file

@ -1,17 +1,19 @@
#ifndef MARSHALLER_H #ifndef MARSHALLER_H
#define MARSHALLER_H #define MARSHALLER_H
#include <stdbool.h>
jsonValue_t* _json_marshall_value(const char* type, void* value); jsonValue_t* _json_marshall_value(const char* type, void* value);
char* _json_marshall(const char* type, void* value); char* _json_marshall(const char* type, void* value);
void* _json_unmarshall_value(const char* type, jsonValue_t* value); void* _json_unmarshall_value(const char* type, jsonValue_t* value);
void* _json_unmarshall(const char* type, const char* json); void* _json_unmarshall(const char* type, const char* json);
void _json_free_struct(const char* type, void* value); void _json_free_struct(const char* type, void* value, bool this);
#define json_marshall(t, v) _json_marshall(# t, (void*) v) #define json_marshall(t, v) _json_marshall(# t, (void*) v)
#define json_unmarshall(t, j) (t*) _json_unmarshall(#t, j) #define json_unmarshall(t, j) (t*) _json_unmarshall(#t, j)
#define json_free_struct(t, v) _json_free_struct(#t, v) #define json_free_struct(t, v) _json_free_struct(#t, v, true)
#endif #endif

View file

@ -36,7 +36,7 @@ void generatePreamble(FILE* output, char* files[], int fileno) {
fprintf(output, "\n"); fprintf(output, "\n");
fprintf(output, "extern void _marshallPanic(const char*, const char*);\n"); fprintf(output, "extern void _marshallPanic(const char*, const char*);\n");
fprintf(output, "extern void _registerMarshaller(int, const char**, jsonValue_t*(*)(void*), void*(*)(jsonValue_t*), void(*)(void*));\n"); fprintf(output, "extern void _registerMarshaller(int, const char**, jsonValue_t*(*)(void*), void*(*)(jsonValue_t*), void(*)(void*, bool));\n");
fprintf(output, "\n"); fprintf(output, "\n");
} }
@ -150,17 +150,28 @@ char* generateFreeFunction(FILE* output, struct structinfo* info, char* suffix)
strcpy(functionName, FREE_FUNCTION_PREFIX); strcpy(functionName, FREE_FUNCTION_PREFIX);
strcat(functionName, suffix); strcat(functionName, suffix);
fprintf(output, "static void %s(void* _d) {\n", functionName); fprintf(output, "static void %s(void* _d, bool this) {\n", functionName);
fprintf(output, "\tif (_d == NULL)\n"); fprintf(output, "\tif (_d == NULL)\n");
fprintf(output, "\t\treturn;\n"); fprintf(output, "\t\treturn;\n");
fprintf(output, "\t%s* d = (%s*) _d;\n", info->names[0], info->names[0]); fprintf(output, "\t%s* d = (%s*) _d;\n", info->names[0], info->names[0]);
for (size_t i = 0; i < info->memberno; i++) { for (size_t i = 0; i < info->memberno; i++) {
struct memberinfo* member = info->members[i]; struct memberinfo* member = info->members[i];
if (member->type->isPointer || strcmp(member->type->type, "string") == 0) { if (member->type->isPointer || strcmp(member->type->type, "string") == 0) {
fprintf(output, "\t_json_free_struct(\"%s\", (void*) d->%s);\n", member->type->type, member->name); fprintf(output, "\t_json_free_struct(\"%s\", (void*) d->%s, true);\n", member->type->type, member->name);
} } else if (!(strcmp(member->type->type, "char") == 0 ||
strcmp(member->type->type, "short") == 0 ||
strcmp(member->type->type, "int") == 0 ||
strcmp(member->type->type, "long") == 0 ||
strcmp(member->type->type, "long long") == 0 ||
strcmp(member->type->type, "float") == 0 ||
strcmp(member->type->type, "double") == 0 ||
strcmp(member->type->type, "bool") == 0
)) {
fprintf(output, "\t_json_free_struct(\"%s\", (void*) &(d->%s), false);\n", member->type->type, member->name);
}
} }
fprintf(output, "\tfree(d);\n"); fprintf(output, "\tif (this)\n");
fprintf(output, "\t\tfree(d);\n");
fprintf(output, "}\n\n"); fprintf(output, "}\n\n");
return functionName; return functionName;