从C中的堆栈中删除后,数据仍在内存中

时间:2013-09-06 07:02:40

标签: c struct

我正在努力提高我对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;
}

2 个答案:

答案 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功能?