#c #memory-leaks #malloc
Вопрос:
Я продолжаю получать следующую ошибку при запуске своей программы:
В нем упоминаются утечки в строках 15, 64 и 110. Я думаю, что ошибка в функции push, но я не вижу, где я мог бы освободить переменную, не вызывая ошибок в моем коде.
Строка 15: struct sNode* new_node = (struct sNode*)malloc(sizeof(struct sNode));
Строка 64: push(amp;stack, exp[i]);
Строка 110: int n = areBracketsBalanced(argv[1]);
Это мой код:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
// structure of a stack node
struct sNode {
char data;
struct sNode* next;
};
void push(struct sNode** top_ref, int new_data);
int pop(struct sNode** top_ref);
void push(struct sNode** top_ref, int new_data){
struct sNode* new_node = (struct sNode*)malloc(sizeof(struct sNode));
if (new_node == NULL) {
printf("Stack overflow n");
getchar();
exit(0);
}
new_node->data = new_data;
new_node->next = (*top_ref);
(*top_ref) = new_node;
}
int pop(struct sNode** top_ref){
char res;
struct sNode* top;
if (*top_ref == NULL) {
printf("Stack overflow n");
getchar();
exit(0);
}else {
top = *top_ref;
res = top->data;
*top_ref = top->next;
free(top);
return res;
}
}
// Returns 1 if character1 and character2 are matching left and right Brackets
bool isMatchingPair(char character1, char character2)
{
if (character1 == '(' amp;amp; character2 == ')')
return 1;
else if (character1 == '{' amp;amp; character2 == '}')
return 1;
else if (character1 == '[' amp;amp; character2 == ']')
return 1;
else
return 0;
}
// Return 1 if expression is balanced
int areBracketsBalanced(char exp[]){
int i = 0;
struct sNode* stack = NULL;
while (exp[i]){
if (exp[i] == '{' || exp[i] == '(' || exp[i] == '[')
push(amp;stack, exp[i]);
if (exp[i] == '}' || exp[i] == ')' || exp[i] == ']') {
if (stack == NULL){
printf("%d: %cn",i,exp[i]);
return 0;
}else if (!isMatchingPair(pop(amp;stack), exp[i])){
printf("%d: %cn",i,exp[i]);
return 0;
}
}
i ;
}
if(stack == NULL){
return 1;
}else{
printf("open: ");
while(stack!=NULL){
int value = pop(amp;stack);
if(value == '('){
printf("%c",')');
}else if(value == '['){
printf("%c",']');
}else if(value == '{'){
printf("%c",'}');
}
}
printf("n");
while(stack!=NULL){
pop(amp;stack);
}
return 0;
}
}
int main(int argc, char* argv[]){
if(argc>1){
int n = areBracketsBalanced(argv[1]);
if(n==0){
return EXIT_FAILURE;
}else if(n==1){
return EXIT_SUCCESS;
}
}
//return 1;
}
Комментарии:
1. @TedLyngmo Я обновил код, надеюсь, это облегчит его понимание.
2. Если скобки не сбалансированы, вы возвращаетесь,
areBracketsBalanced
не открывая остальную часть стека.3. @Barмар Я в замешательстве, должен ли я вытащить остальную часть стека перед возвращением?
4. Да, если вы хотите предотвратить утечку памяти. У вас может быть просто
clear()
функция, которая опустошает стек.5. @Barmar Я отредактировал код, как вы предложили, и он исправил пару других ошибок, но эта все еще сохраняется. Я не понимаю, почему.
Ответ №1:
Вы должны убедиться, что все пути через areBracketsBalanced()
пустой стек будут возвращены. Ты упускаешь это дело:
}else if (!isMatchingPair(pop(amp;stack), exp[i])){
printf("%d: %cn",i,exp[i]);
while (stack != NULL) {
pop(amp;stack);
}
return 0;
}
Поскольку вы делаете это из нескольких мест, я рекомендую определять clear(amp;stack)
функцию вместо того, чтобы каждый раз писать цикл.
Комментарии:
1. О, в этом есть смысл, большое вам спасибо, теперь это работает.