From 995c1d984b6c617d67e7cb35367c4d9fc9802388 Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Mon, 1 Dec 2025 10:36:09 +1100 Subject: [PATCH] Fix memory issues --- src/interpreter.c | 4 +-- src/types.c | 64 ++++++++++++++++++++++++++++++++++------------- src/types.h | 5 +++- 3 files changed, 53 insertions(+), 20 deletions(-) diff --git a/src/interpreter.c b/src/interpreter.c index 10aac7b..b53e446 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -95,7 +95,7 @@ void addVariable(GroundVariable **head, const char *id, GroundValue data) { } GroundVariable* item = malloc(sizeof(GroundVariable)); snprintf(item->id, MAX_ID_LEN, "%s", id); - item->value = data; + item->value = copyGroundValue(&data); HASH_ADD_STR(*head, id, item); } @@ -129,7 +129,7 @@ void interpretGroundInstruction(GroundInstruction inst, GroundScope* scope) { GroundVariable* variable = findVariable(*scope->variables, in->args.args[i].value.refName); if (variable) { free(in->args.args[i].value.refName); // Free the strdup'd refName - in->args.args[i].value.value = variable->value; + in->args.args[i].value.value = copyGroundValue(&variable->value); in->args.args[i].type = VALUE; } else { runtimeError(UNKNOWN_VARIABLE, NULL, in, currentInstruction); diff --git a/src/types.c b/src/types.c index eff3d7a..a389f43 100644 --- a/src/types.c +++ b/src/types.c @@ -44,6 +44,38 @@ GroundValue createListGroundValue(List in) { return gv; } + +GroundValue copyGroundValue(const GroundValue* gv) { + GroundValue newGv; + newGv.type = gv->type; + switch(gv->type) { + case INT: newGv.data.intVal = gv->data.intVal; break; + case DOUBLE: newGv.data.doubleVal = gv->data.doubleVal; break; + case CHAR: newGv.data.charVal = gv->data.charVal; break; + case BOOL: newGv.data.boolVal = gv->data.boolVal; break; + case STRING: + if (gv->data.stringVal != NULL) { + newGv.data.stringVal = strdup(gv->data.stringVal); + } else { + newGv.data.stringVal = NULL; + } + break; + case LIST: { + List newList = createList(); + for (int i = 0; i < gv->data.listVal.size; i++) { + // Recursive call to handle nested lists and other types + appendToList(&newList, copyGroundValue(&gv->data.listVal.values[i])); + } + newGv.data.listVal = newList; + break; + } + case CUSTOM: + newGv.data.customVal = gv->data.customVal; // Shallow copy for custom + break; + } + return newGv; +} + void printGroundValue(GroundValue* gv) { switch (gv->type) { case INT: { @@ -70,6 +102,17 @@ void printGroundValue(GroundValue* gv) { } break; } + case LIST: { + printf("["); + for (int i = 0; i < gv->data.listVal.size; i++) { + printGroundValue(&gv->data.listVal.values[i]); + if (i < gv->data.listVal.size - 1) { + printf(", "); + } + } + printf("]"); + break; + } default: { printf("FIXME"); break; @@ -80,6 +123,7 @@ void printGroundValue(GroundValue* gv) { void freeGroundValue(GroundValue* gv) { if (gv->type == STRING && gv->data.stringVal != NULL) { free(gv->data.stringVal); + gv->data.stringVal = NULL; } if (gv->type == LIST && gv->data.listVal.values != NULL) { List* list = &gv->data.listVal; @@ -87,6 +131,8 @@ void freeGroundValue(GroundValue* gv) { freeGroundValue(&list->values[i]); } free(list->values); + list->values = NULL; + gv->data.listVal = createList(); } } @@ -169,23 +215,7 @@ GroundInstruction copyGroundInstruction(const GroundInstruction* inst) { for (size_t i = 0; i < inst->args.length; i++) { newInst.args.args[i].type = inst->args.args[i].type; if (inst->args.args[i].type == VALUE) { - newInst.args.args[i].value.value = inst->args.args[i].value.value; - if (inst->args.args[i].value.value.type == STRING) { - newInst.args.args[i].value.value.data.stringVal = strdup(inst->args.args[i].value.value.data.stringVal); - } - if (inst->args.args[i].value.value.type == LIST) { - List* origList = &inst->args.args[i].value.value.data.listVal; - List newList = createList(); - for (int j = 0; j < origList->size; j++) { - GroundValue copiedValue = origList->values[j]; - if (copiedValue.type == STRING) { - copiedValue.data.stringVal = strdup(copiedValue.data.stringVal); - } - // Note: this doesn't handle nested lists - you'd need full recursion for that - appendToList(&newList, copiedValue); - } - newInst.args.args[i].value.value.data.listVal = newList; - } + newInst.args.args[i].value.value = copyGroundValue(&inst->args.args[i].value.value); } else { newInst.args.args[i].value.refName = strdup(inst->args.args[i].value.refName); } diff --git a/src/types.h b/src/types.h index 9b50d2e..73c5e2b 100644 --- a/src/types.h +++ b/src/types.h @@ -110,6 +110,9 @@ GroundValue createBoolGroundValue(bool in); // Creates a GroundValue containing (in), with type LIST. GroundValue createListGroundValue(List in); +// Creates a deep copy of a GroundValue +GroundValue copyGroundValue(const GroundValue* gv); + // If (gv) contains any data stored on the heap, frees it. void freeGroundValue(GroundValue* gv); @@ -156,4 +159,4 @@ ListAccess getListAt(List* list, int idx); // Sets an item in list (list) at index (idx) to GroundValue (value). ListAccessStatus setListAt(List* list, int idx, GroundValue value); -#endif +#endif \ No newline at end of file