I got a segfault with this code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
typedef struct _node
{
char *buffer;
struct _node *next;
int node_count;
} node;
typedef struct _list
{
node *head;
node *tail;
} list;
list *node_list;
int list_node_lookup(list *l, char *buffer)
{
node *temp = l->head;
while(temp)
{
if (strcmp(temp->buffer, buffer) == 0)
{
/* We got it earlier */
temp->node_count++;
return 1;
}
else
{
temp = temp->next;
}
}
return 0;
}
int adding_to_list(list *l, char *buffer)
{
int ret;
char *tmp = (char *)malloc(sizeof(char)*(strlen(buffer) + 1));
node *new_node = (node *)malloc(sizeof(struct _node));
/* Empty list */
if (l->head == NULL)
{
strcpy(tmp, buffer);
new_node->buffer = tmp;
new_node->node_count = 0;
l->head = l->tail = new_node;
l->head->next = NULL;
}
else
{
/* The list is not empty */
ret = list_node_lookup(l, buffer);
if (ret == 1)
{
fprintf(stdout, "Got it before\n");
}
else
{
strcpy(tmp, buffer);
new_node->buffer = tmp;
new_node->node_count = 0;
l->tail->next = new_node;
l->tail = new_node;
new_node->next = NULL;
fprintf(stdout, "Adding this cust : %s\n", buffer);
}
}
return 0;
}
int main(int argc, char **argv)
{
FILE *cust;
char buf[BUFSIZ];
DIR* cust_dir;
struct dirent* input;
node_list = (list *) malloc(sizeof(struct _list));
if (node_list == NULL)
{
return 1;
}
node_list->head = node_list->tail = NULL;
if (NULL == (cust_dir = opendir("cust_dir")))
{
return 1;
}
while ((input = readdir(cust_dir)))
{
if (!strcmp (input->d_name, "."))
continue;
if (!strcmp (input->d_name, ".."))
continue;
cust = fopen(input->d_name, "r");
while (fgets(buf, BUFSIZ, cust) != NULL)
{
adding_to_list(node_list, buf);
}
fclose(cust);
}
return 0;
}
When i test my code with a directory that contain this two files(they contain empty lines), i got strange output and seg fault.
I use this file twice (customers.txt and customers_copy.txt) in the same directory:
1
2
3
4 Kristina Chung H Kristina H. Chung Chung, Kristina H.
5 Paige Chen H Paige H. Chen Chen, Paige H.
6 Sherri Melton E Sherri E. Melton Melton, Sherri E.
7 Gretchen Hill I Gretchen I. Hill Hill, Gretchen I.
8 Karen Puckett U Karen U. Puckett Puckett, Karen U.
9 Patrick Song O Patrick O. Song Song, Patrick O.
10 Elsie Hamilton A Elsie A. Hamilton Hamilton, Elsie A.
11
12 Hazel Bender E Hazel E. Bender Bender, Hazel E.
13
The first three lines are empty (when i use one file all is ok, but this multiple files i got a segfault).
Thanks for your help, to understand what’s wrong.
When you add a node to the list (to the tail of the list), you don’t set the
nextpointer of that node to NULL. That means that the next time you do a lookup, you will callstrcmpwith invalid pointers. This in itself could cause a segmentation fault.The simple solution is to set
nextto NULL as soon as you allocate the node.Also, if the node is already in the list, you allocate
tmpbut never use it. That would leak memory. This is similar to the comment by Greg Brown – you are also leaking file descriptors and file handles (you never closecust).[EDIT]
The problem is that you are reading the directory “cust_dir”, so you are getting names of files that are in the directory (e.g. “customers.txt”). You then open the file without adding “cust_dir/” to the file name.
So if by accident you also have the file in the current directory, it works. But otherwise,
custis NULL (becauseinput->d_nameis the name of a file inside “cust_dir”, not in the current directory), and you then try to read data from a NULL file pointer. This causes a segmentation fault.