【发布时间】:2017-11-30 00:22:58
【问题描述】:
我遇到了两个似乎无法解决的内存泄漏实例。第一个实例来自char *temp = (char*)malloc(sizeof(char*));,我在 if 语句的开头使用了这个变量,并确保在最后释放它,但我仍然有泄漏。第二个来自s = create(); 和s = (Stack*)malloc(sizeof(Stack));。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
char **data;
int top;
int size;
}Stack;
typedef enum { FALSE, TRUE } bool;
Stack* create(){
Stack *s;
s = (Stack*)malloc(sizeof(Stack));
s->top = -1;
s->size = 10;
s->data = (char**)malloc(s->size*sizeof(char*));
return s;
}
void deleteStack(Stack* ps){
if(ps == NULL){
printf("No memory allocated in Stack.\n");
}
while(ps->top >= 0){
free(ps->data[ps->top]);
ps->top--;
}
free(ps->data);
}
bool full( Stack s){
if(s.top == s.size-1)
return TRUE;
return FALSE;
}
void push( Stack* ps, char* str){
if(full(*ps)){
int tempsize = ps->size;
ps->size += 10;
ps->data = realloc(ps->data, ps->size * sizeof(char*));
// char **temp = realloc(ps->data, ps->size*sizeof(char*));
// if(temp == NULL){
// perror("realloc");
// printf("Error! memory not allocated.\n");
// exit(-1);
// }
// ps->data = temp;
printf("Stack capacity has grown from %d elements to %d elements\n", tempsize, ps->size);
}
ps->data[++ps->top] = strdup(str);
}
bool empty( Stack s){
if(s.top == -1)
return TRUE;
return FALSE;
}
char* pop( Stack* ps){
if(empty(*ps))
return NULL;
return ps->data[ps->top--];
}
int main(int argc, char *argv[]){
printf("Assignment 2 Problem 1 by Jasmine Ramirez\n\n");
FILE *input = fopen("data_a2.txt", "r");
if(input == NULL){
perror("fopen");
printf("File %s not found.\n", "data_a2.txt");
exit(EXIT_FAILURE);
}
Stack *s;
s = create(); <---16 bytes in 1 block definitely lost
char str[255];
char *temp = (char*)malloc(sizeof(char)); <---1 bytes in 1 block definitely lost
int i = 0;
while(fscanf(input, "%s\n", str) == 1){
if(strcmp(str, "pop") == 0){
temp = pop(s);
i--;
printf("# of elements after popping: %d\tstring popped: %s\n", i, temp);
free(temp);
}
else{
push(s, str);
i++;
}
}
deleteStack(s);
fclose(input);
return 0;
}
我无法弄清楚temp 中丢失1 个字节的原因,而s 应该由deleteStack() 处理。
【问题讨论】:
-
在这段代码中——
char *temp = (char*)malloc(sizeof(char)); int i = 0; while(fscanf(input, "%s\n", str) == 1){ if(strcmp(str, "pop") == 0){ temp = pop(s); i--; printf("# of elements after popping: %d\tstring popped: %s\n", i, temp); free(temp); }泄漏是因为你无条件地用来自pop()的值覆盖了temp,然后释放了pop()返回的内容。这使得无法释放最初分配的内容。最后deleteStack()需要free(ps);。 -
deleteStack在ps == NULL的情况下不应该继续做ps->top -
在编写 C 代码时允许使用空行,让人类可读。
-
同意@Lundin。请使其易于阅读。
标签: c pointers memory memory-leaks