我有这四个文件,
/ 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/