Fix memory issues

This commit is contained in:
2025-12-01 10:36:09 +11:00
parent 6eeccf58fe
commit 995c1d984b
3 changed files with 53 additions and 20 deletions

View File

@@ -95,7 +95,7 @@ void addVariable(GroundVariable **head, const char *id, GroundValue data) {
} }
GroundVariable* item = malloc(sizeof(GroundVariable)); GroundVariable* item = malloc(sizeof(GroundVariable));
snprintf(item->id, MAX_ID_LEN, "%s", id); snprintf(item->id, MAX_ID_LEN, "%s", id);
item->value = data; item->value = copyGroundValue(&data);
HASH_ADD_STR(*head, id, item); 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); GroundVariable* variable = findVariable(*scope->variables, in->args.args[i].value.refName);
if (variable) { if (variable) {
free(in->args.args[i].value.refName); // Free the strdup'd refName 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; in->args.args[i].type = VALUE;
} else { } else {
runtimeError(UNKNOWN_VARIABLE, NULL, in, currentInstruction); runtimeError(UNKNOWN_VARIABLE, NULL, in, currentInstruction);

View File

@@ -44,6 +44,38 @@ GroundValue createListGroundValue(List in) {
return gv; 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) { void printGroundValue(GroundValue* gv) {
switch (gv->type) { switch (gv->type) {
case INT: { case INT: {
@@ -70,6 +102,17 @@ void printGroundValue(GroundValue* gv) {
} }
break; 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: { default: {
printf("FIXME"); printf("FIXME");
break; break;
@@ -80,6 +123,7 @@ void printGroundValue(GroundValue* gv) {
void freeGroundValue(GroundValue* gv) { void freeGroundValue(GroundValue* gv) {
if (gv->type == STRING && gv->data.stringVal != NULL) { if (gv->type == STRING && gv->data.stringVal != NULL) {
free(gv->data.stringVal); free(gv->data.stringVal);
gv->data.stringVal = NULL;
} }
if (gv->type == LIST && gv->data.listVal.values != NULL) { if (gv->type == LIST && gv->data.listVal.values != NULL) {
List* list = &gv->data.listVal; List* list = &gv->data.listVal;
@@ -87,6 +131,8 @@ void freeGroundValue(GroundValue* gv) {
freeGroundValue(&list->values[i]); freeGroundValue(&list->values[i]);
} }
free(list->values); 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++) { for (size_t i = 0; i < inst->args.length; i++) {
newInst.args.args[i].type = inst->args.args[i].type; newInst.args.args[i].type = inst->args.args[i].type;
if (inst->args.args[i].type == VALUE) { if (inst->args.args[i].type == VALUE) {
newInst.args.args[i].value.value = inst->args.args[i].value.value; newInst.args.args[i].value.value = copyGroundValue(&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;
}
} else { } else {
newInst.args.args[i].value.refName = strdup(inst->args.args[i].value.refName); newInst.args.args[i].value.refName = strdup(inst->args.args[i].value.refName);
} }

View File

@@ -110,6 +110,9 @@ GroundValue createBoolGroundValue(bool in);
// Creates a GroundValue containing (in), with type LIST. // Creates a GroundValue containing (in), with type LIST.
GroundValue createListGroundValue(List in); 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. // If (gv) contains any data stored on the heap, frees it.
void freeGroundValue(GroundValue* gv); void freeGroundValue(GroundValue* gv);