繁体   English   中英

执行我的程序时出现奇怪的 dumpcore 错误 (C)

[英]Weird dumpcore error while executing my program (C)

我制作了一个从文件中读取数字的程序,它应该制作一个包含读取数字的列表。

我不确定 while(fscanf ... etc) 。 我可以做什么样的循环来读取所有数字直到文件结束?

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef struct node{
    int info;
    struct node *link;
}Tnode;

typedef Tnode *Tlist;

Tlist CreateList();
Tnode *CreateNode(int x);
Tlist InsertAtEnd(Tlist list,int x);
void PrintList(Tlist list);
void PrintInfo(int nodeinf);

int main(int argc, char** argv) {
    int x,i;
    FILE *pf=fopen("file1.txt","r");
    assert(pf!=NULL);
    Tlist list;
    list=CreateList();

    while(fscanf(pf,"%d",&x)==1){
        list=InsertAtEnd(list,x);
    }
    PrintList(list);

    return (EXIT_SUCCESS);
}
Tnode *CreateNode(int x){
    Tnode *newnode;
    newnode=malloc(sizeof(Tnode));
    assert(newnode!=NULL);
    newnode->info=x;
    newnode->link=NULL;
    return newnode;
    }

Tlist CreateList(){
    return NULL;
}

Tlist InsertAtEnd(Tlist list,int x){
    Tnode *newnode,*tmp;
    newnode=CreateNode(x);
    tmp=list;
    //CASO IN CUI LA LISTA E' ANCORA VUOTA 
    if(tmp==NULL)
        tmp=newnode;
    else{//NEL CASO IN CUI LA LISTA NON E' VUOTA 
        while(tmp->link!=NULL){
            tmp=tmp->link;
        }
        tmp->link=newnode;
    }
    return list;
}

void PrintInfo(int nodeinf){
    printf("%d",nodeinf);
}

void PrintList(Tlist list){
    Tnode *node;
    node=list;
    while (node->link!=NULL){
        PrintInfo(node->info);
        node=node->link;
    }

return;
} 

当我构建它时,它不会给我任何错误。 然后当我运行它时显示

0 [main] simulazione_1 669 cygwin_exception::open_stackdumpfile: Dumping stack trace to simulazione_1.exe.stackdump

RUN FAILED (exit value 35.584, total time: 1s)

那是什么错误。 我的代码有什么问题?

好吧,首先是错误(这里有两个严重错误):

首先,你犯了一个错误:你猜对了,当列表为空(只是一个NULL指针)时,你必须通过指向第一个节点的指针来改变初始指针,但是当你编码时,你不会t 正确考虑并返回原始传递的指针(它继续指向NULL ):

Tlist InsertAtEnd(Tlist list,int x){
    Tnode *newnode,*tmp;
    newnode=CreateNode(x);
    tmp=list;
    //CASO IN CUI LA LISTA E' ANCORA VUOTA 
    if(tmp==NULL)
        tmp=newnode;

您必须更改list指针以返回正确的值,如下所示:

        list=newnode;

或更好:

        return newnode;

其次,在打印函数中,您需要继续while循环,直到节点没有next元素,while(node->link != NULL) )(这将在打印最后一个元素之前结束循环,更糟的是,这就是使您的程序失败的原因,因为您向它传递了一个初始NULL指针,因为您没有正确填充列表,并且您尝试访问node->linknode本身为NULL ,这是一个错误,它是是什么让您的程序崩溃),因此您必须检查指针本身何时为NULL (如while(node != NULL) ),导致:

void PrintList(Tlist list) {
    Tnode *node = list;  /* idem. */

    while (node != NULL) {  /* why not use a for() loop here? */
        PrintInfo(node->info);
        node = node->link;
    }

    return;
} 

或更好:

void PrintList(Tlist list) {
    Tnode *node;

    for (node = list; node != NULL; node = node->link) {
        PrintInfo(node->info);
    }

    return;
} 

断言宏:

assert是一个调试宏,您使用不当。 它向您显示代码失败的行(这很好),以及您传递给它的表达式(这也很好)。 但它有一个你没有考虑过的缺点:在生产代码中,#define #define NDEBUG 1只是为了消除你在代码中所做的所有断言(所有断言都是有条件地编译)是很常见的。 这有一个问题,通过这样做,您代码中的所有断言都会神奇地消失,但这包括您在传递给它的参数中所做的所有测试(这并不好)。 我已经尝试通过一组宏来重写您的所有断言,这些宏将节省输入,并且还可以让您跟踪代码中出现错误的位置。 由于这些宏中没有代码可以有条件地编译它们,因此您可以放心,代码将出现在最终的生产代码中:

#define F(_fmt)  __FILE__":%d: " _fmt, __LINE__

这将扩展:

    printf(F("Error: %s has not been opened\n"), file);

进入:

    printf(__FILE__":%d: " "Error: %s has not been opened\n", __LINE__, file);

或者,假设该语句在文件pru.c第 112 行:

    printf("pru.c" ":%d: " "Error: %s has not been opened\n", 112, file);

这将导致(假设文件是"File1.txt" ):

pru.c:112: Error: File1.txt has not been opened

为了节省您的击键次数,我还定义了一个ERR(fmt, ...)宏来扩展为fprintf(stderr, ...)调用。


易读性

您必须提高代码的易读性,以使其更具可读性。 似乎您是按您在代码中输入的每个空间收费的。

在所有这些修改之后,您修改后的代码如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#define F(_fmt) __FILE__":%d: "_fmt, __LINE__
#define ERR(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)

typedef struct node{
    int info;
    struct node *link;
}Tnode;

typedef Tnode *Tlist;

Tlist CreateList();
Tnode *CreateNode(int x);
Tlist InsertAtEnd(Tlist list, int x);
void PrintList(Tlist list);
void PrintInfo(int nodeinf);

int main(int argc, char** argv)
{
    int x,i;
    char *file_name = "file1.txt";

    FILE *pf=fopen(file_name, "r");
    if (!pf) {
        ERR(F("%s: %s\n"), file_name, strerror(errno));
        exit(EXIT_FAILURE);
    }

    Tlist list = CreateList();  /* it's good to initialize in declarations */

    while(fscanf(pf, "%d", &x) == 1) {
        list = InsertAtEnd(list, x);
    }
    PrintList(list);

    return (EXIT_SUCCESS);
}

Tnode *CreateNode(int x)
{
    Tnode *newnode = malloc(sizeof(Tnode));  /* better initialize in declaration */

    if (!newnode) {
        ERR(F("malloc: %s\n"), strerror(errno));
        exit(EXIT_FAILURE);
    }

    newnode->info = x;
    newnode->link = NULL;

    return newnode;
}

Tlist CreateList()
{
    return NULL;
}

Tlist InsertAtEnd(Tlist list, int x)
{
    Tnode *newnode = CreateNode(x),  /* idem. */ 
          *tmp = list;

    // CASO IN CUI LA LISTA E' ANCORA VUOTA
    if(tmp == NULL) {
        return newnode;  /* return here, you have nothing else to do */
    }

    // NEL CASO IN CUI LA LISTA NON E' VUOTA
    while(tmp->link != NULL) {
        tmp = tmp->link;
    }
    tmp->link = newnode;

    return list;
}

void PrintInfo(int nodeinf) {
    printf("%d\n", nodeinf);  /* you lacked a \n here */
}

void PrintList(Tlist list) {
    Tnode *node = list;  /* idem. */

    while (node != NULL) {  /* why not use a for() loop here? */
        PrintInfo(node->info);
        node = node->link;
    }

    return;
} 

函数InsertAtEnd无效。 当最初列表为空时,函数返回 NULL,因为函数中的指针list未更改。 改变的是指针tmp

使用您的方法,该功能可以如下所示

Tlist InsertAtEnd( Tlist list, int x ) 
{
    Tnode *newnode = CreateNode(x);

    if ( list == NULL )
    {
        list = newnode;
    }
    else
    {    
        Tnode *tmp = list;

        while ( tmp->link != NULL )
        {
            tmp = tmp->link;
        }

        tmp->link = newnode;
    }

    return list;
}

此外,函数PrintList也不正确。 应按以下方式定义

void PrintList( Tlist list )
{
    for (  Tnode *node = list; node != NULL; node = node->link )
    {
        PrintInfo(node->info);
    }
} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM