我有这四个文件,

/ home / user / lib中的tinyll.c tinyll.h

/ home / user / code中的test.c tinyll.h

并按照此说明进行编译以创建静态库
libtinyll.a并使用它。

; in lib
$ gcc -c tinyll.c
$ ar -cvq libtinyll.a *.o

; in code
$ gcc -o test test.c ../lib/libtinyll.a


直到这里一切都OK。但是我不知道为什么会得到分段错误,因为来自[CODE ERROR]但showElements的行有效。目标不是将代码从test.c传递到tinyll.c来处理链接的微小列表。如何解决?

/////////////////////////////////// test.c

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

#include "tinyll.h"

int main(int argc, char *argv[])
{
    progname = argv[0];

    char *file = "fwords";
    int n;
    PTLL lsone = NULL;
    n = loadfileinTLL(file,&lsone);

    // work. good.
    showElements(lsone);

    // [CODE ERROR]
    // Why here dont work?
    // segmentation fault, load the first word
    // but in the second crash.
    while (lsone != NULL) {
        printf("%s",lsone->word);
        lsone = lsone->next;
    }
    return 0;
}

/////////////////////////////////// tinyll.c

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

#include "tinyll.h"

void addElement(PPTLL lst, char data[])
{
    PTLL elemt;
    elemt = (PTLL) malloc(sizeof(TLL));

    if (elemt == NULL) {
        fprintf(stderr, "%s: insufficient memory.\n", progname);
        exit(1);
    }

    if (*lst == NULL)
    {
        strncpy(elemt->word, data, 45);
        elemt->next = NULL;
        *lst = elemt;
    }
    else {
        // add in front of list
        strncpy(elemt->word, data, 45);
        elemt->next = *lst;
        *lst = elemt;
    }
}

void showElements(PTLL lst)
{
    while (lst != NULL) {
        printf("%s\n",lst->word);
        lst = lst->next;
    }
}

int loadfileinTLL(char *filepath, PPTLL plst)
{
    FILE *f;
    if ((f = fopen(filepath, "r")) == NULL) {
        fprintf(stderr, "%s: error to load file %s.\n", progname, filepath);
        exit(1);
    }

    char buf[45]; int n=0;
    while (fgets(buf,sizeof(buf),f) != NULL) {
        char *nl;
        if ((nl = strchr(buf,'\n')) != NULL) {
            *nl = '\0';
        }
        addElement(plst,buf);
        n++;
    }

    fclose(f);

    return n;
}

//////////////////////////////////// tinyll.h

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

#ifndef _TINYLL_
#define _TINYLL_

struct list {
    char word[45];
    struct list *next;
};

// Tiny Linked List
typedef struct list TLL;
typedef struct list *PTLL;
typedef struct list **PPTLL;
char *progname;

#endif

最佳答案

以下代码:

1) compiles cleanly
2) performs correctly, with out seg faulting.
3) checks and handles errors correctly
4) cleans up after itself, by freeing any allocated memory
5) removed leading underscores from names
   as leading underscores has special meaning to the compiler


tinyll.h

#ifndef TINYLL_
#define TINYLL_

struct list
{
    char word[45];
    struct list *next;
};

// Tiny Linked List
typedef struct list TLL;
typedef struct list *PTLL;
typedef struct list **PPTLL;
extern char *progname;

void addElement(PPTLL lst, char data[]);
void showElements(PTLL lst);
int loadfileinTLL(char *filepath, PPTLL plst);


#endif // TINYLL_


tinyll.c

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

 #include "tinyll.h"

void addElement(PPTLL lst, char data[])
{
    PTLL elemt;
    elemt = (PTLL) malloc(sizeof(TLL));

    if (elemt == NULL) {
        fprintf(stderr, "%s: insufficient memory.\n", progname);
        exit(1);
    }

    if (*lst == NULL)
    {
        strncpy(elemt->word, data, 45);
        elemt->next = NULL;
        *lst = elemt;
    }
    else {
        // add in front of list
        strncpy(elemt->word, data, 45);
        elemt->next = *lst;
        *lst = elemt;
    }
}

void showElements(PTLL lst)
{
    while (lst != NULL) {
        printf("%s\n",lst->word);
        lst = lst->next;
    }
}

int loadfileinTLL(char *filepath, PPTLL plst)
{
    int n=0;

    FILE *f;
    if ((f = fopen(filepath, "r")) == NULL)
    {
        fprintf(stderr, "%s: error to load file %s.\n", progname, filepath);
        n = -1;
    }

    else
    {
        char buf[45];

        while (fgets(buf,sizeof(buf),f) != NULL)
        {
            char *nl;
            if ((nl = strchr(buf,'\n')) != NULL)
            {
                *nl = '\0';
            }
            addElement(plst,buf);
            n++;
        }

        fclose(f);
    } // endif

    return n;
}


测试

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

#include "tinyll.h"

char *progname;

int main(int argc, char *argv[])
{
    if( 1 == argc )
    {
        progname = argv[0];
    }
    else
    {
        printf( "USAGE: %s\n", argv[0]);
        exit( EXIT_FAILURE );
    }

    // implied else, right number (0) of arguments on command line

    char *file = "fwords";
    int n;
    PTLL lsone = NULL;
    PTLL lstwo = NULL;

    n = loadfileinTLL(file,&lsone);

    if( n > 0 )
    {

        // work. good.
        showElements(lsone);

        // [CODE ERROR]
        // Why here dont work?
        // segmentation fault, load the first word
        // but in the second crash.
        lstwo = lsone;
        while (lstwo)
        {
            printf("%s",lstwo->word);
            lstwo = lstwo->next;
        }
    } // endif

    while( lsone )
    {
        lstwo = lsone->next;
        free(lsone);
        lsone = lstwo;
    } // end while

    return 0;
}


我将以下内容用于测试文件:

one
two
three
four
five
six


输出为:

six
five
four
three
two
one
sixfivefourthreetwoone

关于c - C中的微小链接列表错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31815114/

10-12 05:29