C

时间:2015-08-04 16:58:14

标签: c gcc

我有这四个文件,

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

test.c tinyll.h在/ home / user / code

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

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

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

直到这里一切都好。但我不知道为什么我会因为来自[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 个答案:

答案 0 :(得分:0)

以下代码:

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;
}

test.c的

#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