Fix memory issues
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
64
src/types.c
64
src/types.c
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user