为什么strcpy会读取多余的字符?

时间:2013-05-14 18:59:04

标签: c tree

我只有一个关于制作二叉树的问题,因为这段代码不起作用,它将节点放在不应该去的地方,虽然它永远不会像破坏的管道一样崩溃其泄漏的内存。这个想法是一个简单的猜谜游戏,它只是试图猜测你在想什么,当它出错时你输入一个问题和答案来帮助它学习。相关代码:

我猜我的主要问题是char * guess有时只存储传递给getnew()的原始字符串的片段。下一个是traverse()中的逻辑,因为无论用户输入如何,它都会跳转到“no”状态。

struct binary {
    unsigned long ID;
    char *guess;
    char isAns;
    struct binary *yes;
    struct binary *no;
};
typedef struct binary Node;

void traverse(Node **top)
{
    if(*top)
    {    
        char ans[128] = "ok";
        char ans2[128] = "ok";
        if((*top)->isAns=='y')
        {
            fprintf(stdout,"Is it %s (y/n)? ",(*top)->guess);
        }
        else
        {
            fprintf(stdout,"%s (y/n)? ",(*top)->guess);
        }
        while(!fgets(ans,128,stdin));
        if((*top)->isAns=='y')
        {
            if(ans=="y")
            {
                printf("Successful string of guesses!\n");
            }
            else
            {
                printf("Enter another question to figure out the difference: ");
                while(!fgets(ans,128,stdin));
                Node *q=getnew(ans,'n');
                printf("Enter the right answer: ");
                while(!fgets(ans2,128,stdin));
                push1(top,q,'n');
                (*top)->yes = getnew(ans2,'y');
            }
        }
        else
        {
            if(ans=="y")
            {
                if((*top)->yes)
                {
                    traverse(&(*top)->yes);
                }
                else
                {
                    printf("Null node for top->yes\n");
                    printf("Enter an answer: ");
                    while(!fgets(ans,128,stdin));
                    (*top)->yes=getnew(ans,'y');
                }
            }
            else
            {
                if((*top)->no)
                {
                    traverse(&(*top)->no);
                }
                else
                {
                    printf("Null node for top->no\n");
                    printf("Enter an answer: ");
                    while(!fgets(ans,128,stdin));
                    (*top)->no=getnew(ans,'y');
                }
            }
        }
    }
    else
    {
        char ques[128] = "ok";
        char ans[128] = "ok";
        printf("Node is null\n");
        printf("Put in a question and answer to yes condition\n");
        printf("Enter question: ");
        while(!fgets(ques,128,stdin));
        printf("Enter answer for yes condition: ");
        while(!fgets(ans,128,stdin));
        (*top) = getnew(ques,'n');
        (*top)->yes=getnew(ans,'y');
    }
    printf("\n\n");
}



Node * getnew(char *msg, char isAns)
{
    Node *nnew = malloc(sizeof(Node));
    nnew->ID=clock();
    nnew->guess=malloc(sizeof(msg));
    strcpy(nnew->guess,msg);
    nnew->isAns=isAns;
    nnew->yes=0;
    nnew->no=0;
    return nnew;
}

我感谢任何帮助。

3 个答案:

答案 0 :(得分:3)

nnew->guess=malloc(sizeof(msg));仅为指针分配足够的内存。

而不是:

nnew->guess=malloc(sizeof(msg));
strcpy(nnew->guess,msg);

使用:

nnew->guess=strdup(msg);

答案 1 :(得分:0)

我看到guessmalloc的位置,但我看不到free的位置。这肯定会导致内存泄漏。


作为附注,我刚刚启动了一个快速程序来检查

nnew->guess=malloc(sizeof(msg));

看起来像这样

char str[10] = "string";
printf("%d", sizeof(str));

令人惊讶的是,它打印了10

但这种分配方法仍让我感到不安。

答案 2 :(得分:0)

您可能想要使用strdup

C字符串是char *指针,因此`sizeof(msg)== sizeof(char *)== 8或4“。不是你想要的。

nnew->guess=malloc(sizeof(msg));
strcpy(nnew->guess,msg);

应该是

nnew->guess = strdup(msg);

或者     nnew-> guess = malloc(strlen(msg)+ 1);     strcpy(nnew-> guess,msg + 1);

+1代表nul终结符(假设您需要它)。