我正在努力提高我对C.的了解。
作为练习,我写了一个堆栈数据结构。如果我推N个项目然后弹出N个项目,一切正常。当我尝试再次推送项目时,问题就出现了,因为最后一个删除的项目仍然在内存中(我认为这是一个问题)。
当我为新路径结构分配内存时,最后删除的字符串仍然是在弹出数据后释放的地址。 因此,当推送新字符串时,最后删除的字符串和新字符串将被连接。
有人可以检查下面的代码并告诉我我做错了什么。其他评论也欢迎。感谢。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 1000
struct path {
char curPath[N];
struct path *Next;
};
struct MyStack {
struct path *head;
int size;
};
int push(struct MyStack *, char *);
char * pop(struct MyStack *, char *);
int main() {
char path[N];
struct MyStack stack;
stack.head = NULL;
stack.size = 0;
push(&stack, "aaaaaaaaaaaa");
push(&stack, "bbbbbbbbbbbb");
pop(&stack, path);
printf("%s\n", path);
// output is:
// bbbbbbbbbbbb
path[0] = '\0';
push(&stack, "cccccccccccc");
pop(&stack, path);
printf("%s\n", path);
// output should be:
// cccccccccccc
// but it is not
// it is:
// bbbbbbbbbbbbcccccccccccc
return 0;
}
int push(struct MyStack *stack, char *path) {
if (strlen(path) > N) {
return -1;
}
struct path *p = (struct path*)malloc(sizeof(struct path));
if (p == NULL) {
return -1;
}
strcat((*p).curPath, path);
(*p).Next = (*stack).head;
(*stack).head = p;
(*stack).size++;
return 0;
}
char * pop(struct MyStack *stack, char *path) {
if ((*stack).size == 0) {
printf("can't pop from empty stack");
return NULL;
}
struct path *p;
p = (*stack).head;
(*stack).head = (*p).Next;
strcat(path, (*p).curPath);
free(p);
p = NULL;
(*stack).size--;
return path;
}
答案 0 :(得分:3)
malloc()
没有用零填充分配的内存,所以这里
struct path *p = (struct path*)malloc(sizeof(struct path));
// ...
strcat((*p).curPath, path);
你将给定的字符串追加到(*p).curPath
中的任何内容。
(这可能会轻易导致分段违规。)
使用strcpy()
或(或许更好strlcpy()
)可以解决问题。
答案 1 :(得分:3)
您在strcat()
功能中使用pop()
。这会将stack->head
处的字符串附加到char path[]
。如果要替换字符串,请使用strcpy()
而不是strcat()
。
除此之外,您的代码还有其他奇怪之处。您将从int
返回push()
,从char*
返回pop()
,但您没有将这些变量分配给main()
中的任何内容,那么为什么不void
功能?