2

我在视觉工作室中使用视觉泄漏检测器,当我运行程序时它会检测到一些泄漏。基本上,程序中有两个泄漏,一个是在 malloc 的结构 *p 上检测到的,另一个是在其成员(p->word)中检测到的。我阅读了您关于在 malloc 结构中释放内存的所有讨论。问题是我似乎找不到可以释放内存的地方,尤其是当这是一个递归结构时。

这是代码

#include <stdio.h>
#include <ctype.h>
#include <string.h>

#include <stdlib.h>
#include <vld.h>

#define MAXWORD 100

struct tnode { /*the tree node */
    char *word; /* points to itself */
    int count; /* number of occurences */
    struct tnode *left; /* left child */
    struct tnode *right; /* right child */
};


struct tnode *addtree (struct tnode *, char *);
struct tnode *talloc(void);
void treeprint (struct tnode *);
char *strdupli (char *s);
int getword (char *, int);
void strcopy (char *, const char *);

int main(void)
{
    struct tnode *root;
    char word[MAXWORD];

    root = NULL;
    while(getword(word, MAXWORD) != EOF)
        if( isalpha (word[0]))
            root = addtree(root, word);
        treeprint(root);
        return 0;
}



int getword(char *word, int lim)
{
    int c, getch(void);
    void ungetch(int);
    char *w = word;

    while(isspace(c = getch()))
        ;
    if(c != EOF)
        *w++ = c;
    if(!isalpha(c)) {
        *w = '\0';
        return c;
    }
    for( ; --lim > 0; w++)
        if(!isalnum(*w = getch())) {
            ungetch(*w);
            break;
        }
    *w = '\0';
    return word[0];

}

struct tnode *addtree (struct tnode *p, char *w)
{
    int cond;

    if (p == NULL) { /* a new word has arrived*/
        p = talloc(); /* make a new node */
        p->word = strdupli(w);
        p->count = 1;
        p->left = p->right = NULL;
    } else if ((cond=strcmp(w, p->word))==0)
        p->count++;
    else if (cond < 0)
    {
        p->left = addtree (p->left, w);
    } else
    {
        p->right = addtree(p->right, w);
    }
    return p;
}

void treeprint (struct tnode *p)
{
    if(p != NULL) {
        treeprint(p->left);
        printf("%4d %s\n", p->count, p->word);
        treeprint(p->right);
    }
}


/* talloc: make a tnode */
struct tnode *talloc(void)
{
    return (struct tnode *) malloc(sizeof(struct tnode));
}

char *strdupli (char *s) /* make a duplicate of s */
{
    char *p;
    p = (char *) malloc (strlen(s) + 1);
    if (p != NULL)
        strcopy(p, s);
    return p;
}

void strcopy (char *s, const char *t)
{
        while ((*s++ = *t++) != '\0')
        ;
}

#define BUFSIZE 100
char buf[BUFSIZE]; /* buffer for ungetch */
int bufp = 0; /* next free position in buf */
int getch(void) /* get a (possibly pushed-back) character */
{
    return (bufp > 0) ? buf[--bufp] : getchar();
}

void ungetch(int c) /* push character back on input */
{
    if (bufp >= BUFSIZE)
        printf("ungetch: too many characters\n");
    else
        buf[bufp++] = c;
}

你需要看看 *addtree 函数

4

2 回答 2

3

为了解决这个问题,创建一个看起来像你的打印函数的递归函数来释放你的树。

一个例子 :

void free_tree (struct tnode *p)
{
    if(p != NULL) {
        free_tree(p->left);
        free_tree(p->right);
        free( p->word );
        free( p );
    }
}

你可以把它放在主要之后treeprint

int main(void)
{
    ...
    treeprint(root);
    free_tree( root );
    // ^^^^^^^^^^^^^^^
    return 0;
}
于 2013-07-04T06:10:11.500 回答
2

在这种情况下,您可以编写一个递归函数来在完成操作后释放树。与此代码的风格保持一致:

void tfree(struct tnode *p) 
{ 
    if (p != NULL) {
        tfree(p->left);
        tfree(p->right);
        free(p->word);
        free(p);
    }     
}

请注意,在程序结束时仍可访问的分配内存并不是真正的泄漏,因为操作系统会清理它。这里有一些有趣的讨论,特别是这个答案

当然,用完后释放内存是一种很好的方式,但我会更关心已分配但现在无法访问的内存。

于 2013-07-04T06:10:18.120 回答