Shell simulation using lists - c

Now i'm learning C and I have a problem with memory alocation, atleast this I understand from my code error.
Code
#ifndef __FILE_H__
#define __FILE_H__
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct Files Files;
typedef struct DirList DirList;
typedef struct NodeFile NodeFile;
typedef struct NodeDir NodeDir;
typedef struct Directory {
// The name of the directory
char *name;
// TODO: The list of files of the current directory
Files *files;
// TODO: The list of dirs of the current directory
DirList *dirs;
// The parent directory of the current directory (NULL for the root
// directory)
struct Directory *parentDir;
} Directory;
// DO NOT MODIFY THIS STRUCTURE
typedef struct File {
// The name of the file
char *name;
// The size of the file
int size;
// The content of the file
char *data;
// The directory in which the file is located
Directory *dir;
} File;
typedef struct Files {
NodeFile *first;
NodeFile *last;
} Files;
typedef struct DirList {
NodeDir *first;
NodeDir *last;
} DirList;
typedef struct NodeFile {
struct NodeFile *next;
struct NodeFile *prev;
File *newfile;
} NodeFile;
typedef struct NodeDir {
struct NodeDir *next;
struct NodeDir *prev;
Directory *newdir;
} NodeDir;
// create root of file system
void makeroot(Directory **root)
{
*root = (Directory *) malloc(sizeof(Directory));
(*root)->parentDir = NULL;
(*root)->name = strdup("/");
(*root)->files = NULL;
(*root)->dirs = NULL;
}
// remove root of file system
void deleteroot(Directory *root)
{
root = NULL;
free(root);
}
//add new file to current directory
File *touch(Directory *root, char *nume, char *content)
{
NodeFile *new = (NodeFile *) malloc(sizeof(NodeFile));
new->newfile = (File *) malloc(sizeof(File));
new->newfile->name = (char *) malloc(strlen(nume) + 1);
new->newfile->data = (char *) malloc(strlen(content) + 1);
strcpy(new->newfile->name, nume);
strcpy(new->newfile->data, content);
if (root->files == NULL) {
root->files = (Files *) malloc(sizeof(Files));
root->files->first = (NodeFile *) malloc(sizeof(NodeFile));
root->files->last = (NodeFile *) malloc(sizeof(NodeFile));
//if no file in folder root has first and last position
root->files->first = new;
root->files->last = new;
} else if (strcmp(root->files->first->newfile->name,
new->newfile->name) > 0) {
new->next = root->files->first;
root->files->first = new;
} else if (strcmp(root->files->last->newfile->name,
new->newfile->name) < 0) {
root->files->last->next = new;
root->files->last = new;
} else {
NodeFile *i = root->files->first;
while (i != root->files->last) {
if (strcmp(i->next->newfile->name,
new->newfile->name) > 0) {
if (i == root->files->first->next)
i = root->files->first;
i->next->prev = new;
new->next = i->next;
new->prev = i;
i->next = new;
break;
}
i = i->next;
}
}
return new->newfile;
}
// Create directory
Directory *mkdir(Directory *parent, char *name)
{
NodeDir *new = (NodeDir *) malloc(sizeof(NodeDir));
//new->newdir = (Directory *) malloc(sizeof(Directory));
new->newdir = (Directory *) malloc(strlen(Directory) + 1);
new->newdir->name = (char *) malloc(strlen(name) + 1);
strcpy(new->newdir->name, name);
new->newdir->parentDir = parent;
if (parent->dirs == NULL) {
parent->dirs = (DirList *)malloc(sizeof(DirList));
parent->dirs->first = (NodeDir *) malloc(sizeof(NodeDir));
parent->dirs->last = (NodeDir *) malloc(sizeof(NodeDir));
parent->dirs->first = new;
parent->dirs->last = new;
} else if (strcmp(parent->dirs->first->newdir->name,
new->newdir->name) > 0) {
new->next = parent->dirs->first;
parent->dirs->first = new;
} else if (strcmp(parent->dirs->last->newdir->name,
new->newdir->name) < 0) {
parent->dirs->last->next = new;
parent->dirs->last = new;
} else {
NodeDir *i = parent->dirs->first->next;
while (i != NULL) {
if (strcmp(i->newdir->name, new->newdir->name) > 0) {
if (i == parent->dirs->first->next)
i = parent->dirs->first;
i->next->prev = new;
new->next = i->next;
new->prev = i;
i->next = new;
break;
}
i = i->next;
}
}
return new->newdir;
}
// traverse list and print files and folders names
void ls(Directory *parent)
{
if (parent->files != NULL) {
NodeFile *i;
for (i = parent->files->first; i != NULL; i = i->next)
printf("%s ", i->newfile->name);
}
if (parent->dirs != NULL) {
NodeDir *j;
for (j = parent->dirs->first; j != NULL; j = j->next)
printf("%s ", j->newdir->name);
}
printf("\n");
}
// working directory
void pwd(Directory *dir)
{
if (dir->parentDir == NULL)
return;
if (dir->parentDir != NULL) {
pwd(dir->parentDir);
printf("/%s", dir->name);
}
}
Directory *cd(Directory *dir, char *where)
{
if (strcmp(where, "..") == 0 && dir->parentDir != NULL) {
return dir->parentDir;
} else if (dir->dirs == NULL)
printf("Cannot move to ‘%s’: No such directory!\n", where);
else {
NodeDir *it = dir->dirs->first;
while (it != NULL) {
if (strcmp(it->newdir->name, where) == 0) {
dir = it->newdir;
break;
}
it = it->next;
}
if (it == NULL)
printf("Cannot move to ‘%s’: No such directory!\n",
where);
free(it);
}
return dir;
}
void tree(Directory *parent, int i)
{
if (i == 1)
printf("\n%s\n", parent->name);
if (parent->files != NULL) {
NodeFile *it;
for (it = parent->files->first; it != NULL; it = it->next) {
if (i != 1) {
int j;
for (j = 0; j < i; j++)
printf(" ");
}
printf(" %s\n", it->newfile->name);
}
free(it);
}
if (parent->dirs != NULL) {
NodeDir *it = parent->dirs->first;
while (it != NULL) {
int j;
for (j = 0; j < i; j++)
printf(" ");
printf("%s\n", it->newdir->name);
i = i + 1;
tree(it->newdir, i);
it = it->next;
i = i - 1;
}
free(it);
}
}
void rm(Directory *parent, char *dirname)
{ //it -- item
NodeFile *it;
for (it = parent->files->first; it != NULL; it = it->next) {
if (strcmp(it->newfile->name, dirname) == 0) {
if (it == parent->files->first) {
parent->files->first =
parent->files->first->next;
} else if (it == parent->files->last) {
parent->files->last = it->prev;
} else {
it->prev->next = it->next;
it->next->prev = it->prev;
}
it = NULL;
free(it);
return;
}
}
if (it == NULL) {
printf("Cannot remove ‘%s’: No such file!\n", dirname);
free(it);
}
}
void rmdir(Directory *parent, char *dirname)
{
NodeDir *it;
for (it = parent->dirs->first; it != NULL; it = it->next) {
if (strcmp(it->newdir->name, dirname) == 0) {
if (it == parent->dirs->first) {
parent->dirs->first =
parent->dirs->first->next;
} else if (it == parent->dirs->last) {
parent->dirs->last =
parent->dirs->last->prev;
} else {
it->prev->next = it->next;
it->next->prev = it->prev;
}
it = NULL;
free(it);
return;
}
}
if (it == NULL) {
printf("Cannot remove ‘%s’: No such directory!\n", dirname);
free(it);
}
}
#endif
/* __FILE_H__ */
Valgrind output:
> create fs ls
>
> ls
>
> mkdir test ls
> ==11466== Conditional jump or move depends on uninitialised value(s)
> ==11466== at 0x109025: ls (file.h:189)
> ==11466== by 0x1097D4: main (main.c:86)
> ==11466== Uninitialised value was created by a heap allocation
> ==11466== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
> ==11466== by 0x108D44: mkdir (file.h:134)
> ==11466== by 0x109766: main (main.c:81)

In touch you missed to set to NULL the fields next and rev
In mkdir you missed to set to NULL the fields files and dirs, and sometimes next
To simplify your code and makes it robust I encourage you to add for each struct a constructor doing the malloc and initializing all the fields including with NULL when the value is not yet known, and also add a destructor for each to free all allocated element. Of course in your case you can also use calloc rather than malloc to put all to 0
deleteroot does not free memory because you set root to NULL before to call free, and because you do not follow the links to free linked resources.
In rmdir you have the same unexpected assignment to NULL before to call free inside the for. At the end if is useless to check if it is NULL because the continuation test of the for is it != NULL, and the free in the last block is useless
Out of the memory leaks because you never free the resources you also introduce memory leaks in mkdir doing
parent->dirs->first = (NodeDir *) malloc(sizeof(NodeDir));
parent->dirs->last = (NodeDir *) malloc(sizeof(NodeDir));
parent->dirs->first = new;
parent->dirs->last = new;
the two first lines must be removed
In
new->newdir = (Directory *) malloc(strlen(Directory) + 1);
strlen(Directory) is invalid, must be
new->newdir = (Directory *) malloc(sizeof(Directory));
In pwd you do
if (dir->parentDir == NULL)
return;
if (dir->parentDir != NULL) {
in that the two first lines are useless
Furthermore you print nothing in case of root, can be :
void pwd(Directory *dir)
{
if (dir->parentDir != NULL) {
pwd(dir->parentDir);
printf("%s/", dir->name);
}
else
putchar('/');
}
In cd the call to free must be removed
In case of .. if there is a parent you will always indicate an error because you consider the sub dirs. Note that at the root level a cd .. does nothing, so replace
if (strcmp(where, "..") == 0 && dir->parentDir != NULL) {
return dir->parentDir;
} else if (dir->dirs == NULL)
by
if (strcmp(where, "..") == 0) {
return (dir->parentDir != NULL) ? dir->parentDir : dir;
} else if (dir->dirs == NULL)
I encourage you to rename the field newfile to file and newdir to dir because the new has no reason
In tree the call to free must be removed
Visibly all is in a header file, I encourage you to put only the struct definitions and function declaration in the header file, and to move the function definitions in a source file, else if you #include several times your header file you will have functions multiply defined

Related

How to properly display names of directories and their subdirectories from a linked list?

Im trying to store the names of directories and sub directories in a linked list. Something like a basic DOS commands (mkdir, cd.., cd dir, dir, and delete). I would like to make a dir funcntion to display the subdirectories of the current directory. I just have no idea how to implement that. I made push and pop functions for stack as well. Can you help me out please?
MY CODE:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include <stdlib.h>
#include<string.h>
#define MAX_DIR_LENGTH (256)
typedef struct dir* Position;
typedef struct stack* StackPosition;
struct dir {
char name[MAX_DIR_LENGTH];
Position sibling;
Position child;
Position next;
};
struct stack {
Position dir;
StackPosition next;
};
Position createDir(char* name) {
Position dir = (Position)malloc(sizeof(dir));
if (!dir) {
printf("Memory allocation failed!\n");
return NULL;
}
strcpy(dir->name, name);
dir->child = NULL;
dir->sibling = NULL;
}
void push(char x, StackPosition S) {
StackPosition q;
q = (StackPosition)malloc(sizeof(struct stack));
q->dir = x;
q->next = S->next;
S->next = q;
}
int pop(StackPosition S) {
int x = -1;
StackPosition temp;
if (S->next != NULL) {
x = S->next->dir;
temp = S->next;
S->next = temp->next;
free(temp);
}
return x;
}
int md(Position current, char* name) {
if (current->child == NULL) {
current->child = createDir(name);
//if (!dir)return-1;
}
else {
Position dir = createDir(name);
if (!dir)return -1;
if (strcmp(current->child->name, name) > 0) {
dir->sibling = current->child;
current->child = dir;
}
else {
Position tmp = current->child;
while (strcmp(tmp->sibling->name, name) < 0) {
tmp = tmp->sibling;
}
dir->next = tmp->next;
tmp->next = dir;
}
}
return 0;
}
Position cd(Position current, char* name, StackPosition stack) {
Position p = current->child;
while (p != NULL && strcmp(p->name, name) != 0) {
p = p->sibling;
}
if (!p) {
printf("Directory not found, please try again!\n");
return current;
}
push(name, stack);
return p;
}
Position cdBack(StackPosition stack, Position current) {
if (stack->next != NULL) {
StackPosition first = stack->next;
Position result = first->dir;
stack->next = first->next;
free(first);
return result;
}
return current;
}
void delete(Position current) {
if (!current)return;
delete(current->sibling);
delete(current->child);
free(current);
}
int main() {
char c;
char ime[MAX_DIR_LENGTH];
Position root = NULL;
Position current = NULL;
struct stack stack;
stack.next = NULL;
root = createDir("C:");
current = root;
//md(current, "John");
//current = cdBack(&stack, current);
while (1)
{
printf("1->mkdir\n2->cd dir\n3->cd..\n4->dir\n5->Izlaz\nYour choice: ");
scanf("%c", &c);
printf("\n");
switch (c) {
case'1':
printf("Enter name:");
scanf("%s", ime);
md(current, ime);
break;
case'2':
printf("Enter the directory where you want to enter:");
scanf("%s",ime);
cd(current, ime, &stack);
break;
case'3':
current = cdBack(&stack, current);
break;
case'4':
break;
case'5':
return 0;
break;
}
}
}

Removing items from a tree structure

I have this struct:
typedef struct Tree {
int arrel;
struct Tree *dret;
struct Tree *esq;
unsigned int talla;
} Tree;
With the following methods:
void crearArbre (struct Tree *arbre, int val_arrel)
{
arbre->arrel = val_arrel;
arbre->dret = NULL;
arbre->esq = NULL;
arbre->talla = 0;
}
int inserir (struct Tree *arbre, int valor) //Insert method
{
struct Tree *aux = arbre;
struct Tree *ant = NULL;
while (aux != NULL && aux->arrel - valor != 0)
{
ant = aux;
if (aux->arrel > valor)
{
aux = aux->esq;
}
else
aux = aux->dret;
}
if (aux == NULL)
{
if (ant->arrel > valor)
{
//ant -> esq -> arrel = valor;
ant->esq = (struct Tree *) malloc (sizeof (struct Tree));
ant->esq->arrel = valor;
//crearArbre(ant -> esq ,valor);
}
else
{
ant->dret = (struct Tree *) malloc (sizeof (struct Tree));
ant->dret->arrel = valor;
}
}
arbre->talla += 1;
return 0;
}
int rem (struct Tree *arbre, int valor) //Remove method
{
if (arbre == NULL)
return NULL;
if (valor < arbre->arrel)
{
return rem (arbre->esq, valor);
}
else if (valor > arbre->arrel)
{
return rem (arbre->dret, valor);
}
else
{
int val = arbre->arrel;
arbre = NULL; //Not sure about this
free (arbre); //?
return val;
}
}
void printarArbre (struct Tree *arbre) //Post order printing method
{
if (arbre != NULL)
{
printarArbre (arbre->esq);
printarArbre (arbre->dret);
printf ("%d -> ", arbre->arrel);
}
}
I have been testing the struct by inserting some numbers, find them and finally remove some elements. But, after I remove an element from the tree and calling free(), if I call printarArbre(), in the position that was the element previously removed, if I set (arbre = NULL) and then free(arbre), why is it still being printed? Do I need a flag to indicate whether a node has been removed?
Please see also the comments. The proper way would be:
int rem (struct Tree **arbreIn, int valor) //Remove method
{
struct Tree *arbre= *arbreIn; // shorthand
if (arbre == NULL)
return NULL;
if (valor < arbre->arrel)
{
return rem (&(arbre->esq), valor);
}
else if (valor > arbre->arrel)
{
return rem (&(arbre->dret), valor);
}
else
{
int val = arbre->arrel;
free (arbre); // free the node
*arbreIn = NULL; // set the parent's pointer (esq or dret) to null
return val;
}
}

circular linked list not working properly in c windows

I tried to implement circular linked list to manage a set of tasks by a server side application. The application is multi-threaded where one thread (updater() ) reads the linked list only for read while another two (push_stream() and delete_stream()) access the linked list to add to and delete from the linked list respectively.
My problem is not all the files to be deleted (after being processed) are deleted.
struct data_stream
{
bool processed;
int count;
char filename[30];
int TYPE_GRP;
int task_type;
struct data_stream *next;
};
struct data_stream *stream_head=NULL; //global variable
main(partial code)
main()
{
_beginthread(updater, 0, NULL);
while ((new_socket = accept(srv_sock, (struct sockaddr *)&client, &c)) != INVALID_SOCKET)
{
_beginthreadex(0, 0, handle_client, &new_socket, 0, 0);
}
}
handle_client function (partial code)
handle_client()
{
//some where in handle_client
EnterCriticalSection(&stream_lock);
stream_head = push_stream(&stream_head, TYPE_GRP, task_type);
LeaveCriticalSection(&stream_lock);
}
updater function (full source code)
void updater(void *data)
{
while (1)
{
struct data_stream*temp = stream_head;
struct data_stream*first = stream_head;
struct data_stream*prev = NULL;
if (stream_head != NULL)
{
struct data_stream*next = NULL;
do
{
next = temp->next;
if (temp->processed == false&&temp->task_type == 2)
{
process_files(temp);
}
else if (temp->processed == false&&temp->task_type == 3)
{
process_others();
}
EnterCriticalSection(&stream_lock);
temp->processed = true;
LeaveCriticalSection(&stream_lock);
temp = next;
} while (temp != first);
}
if (stream_head != NULL)
{
EnterCriticalSection(&stream_lock);
stream_head=delete_stream(&stream_head);
LeaveCriticalSection(&stream_lock);
}
Sleep(6000);
}
}
process_files
void process_files(struct data_stream*temp)
{
int count = 0;
char file_to_update[50] = { NULL };
size_t name_len = strlen(temp->filename);
memcpy_s(file_to_update, name_len, temp->filename, name_len);
file_to_update[name_len] = '\0';
temp->count = 0;
FILE *list_to_update ;
fopen_s(&list_to_update , file_to_update, "r+b");
if (list_to_update != NULL)
{
char readline[100] = { '\0' };
while (fgets(readline, sizeof(readline), list_to_update ) != NULL)
{
//read a line at a time and process the list
count++;
}
temp->count = count;
fclose(list_to_update );
}
else
printf("\nerror opening file\n");
}
process_others()
void process_others(struct data_stream*temp)
{
int count = 0;
char file_to_update[50] = { NULL };
size_t name_len = strlen(temp->filename);
memcpy_s(file_to_update, name_len, temp->filename, name_len);
file_to_update[name_len] = '\0';
temp->count = 0;
FILE *list_to_update ;
fopen_s(&list_to_update , file_to_update, "r+b");
if (list_to_update != NULL)
{
char readline[100] = { '\0' };
while (fgets(readline, sizeof(readline), list_to_update ) != NULL)
{
//read a line at a time and process the list
count++;
}
temp->count = count;
fclose(list_to_update );
}
else
{
printf("\nerror opening file\n");
}
}
}
push_stream (full source code)
struct data_stream* push_stream(struct data_data_stream**head_ref, int typ_grp, int task_type)
{
struct data_stream*new_data_stream=
(struct data_data_stream*)malloc(sizeof(struct data_stream));
new_stream->processed = false;
new_stream->task_type = task_type;
new_stream->TYPE_GRP = typ_grp;
new_stream->filename[0] = NULL;
new_stream->count = 0;
new_stream->next = NULL;
if (task_type == 2)
sprintf_s(new_stream->filename, "%s%03d.txt", "file_md5_list_", stream_count);
else
sprintf_s(new_stream->filename, "%s%03d.txt", "other_list_", stream_count);
if (*head_ref == NULL)
{
*head_ref = new_stream;
new_stream->next = new_stream;
}
else
{
struct data_stream* last = (*head_ref)->next;
struct data_stream* prev = (*head_ref)->next;
while (last != *head_ref)
{
prev = last;
last = last->next;
}
new_stream->next = *head_ref;
last->next = new_stream;
}
if (stream_count > 998)
stream_count = 1;
else
stream_count++;
return new_stream;
}
delete_stream function (full source code)
struct data_stream* delete_stream(struct data_data_stream**head)
{
if (head == NULL)
return NULL;
struct data_stream*prev = NULL;
struct data_stream*temp = *head;
struct data_stream*first = *head;
do
{
struct data_stream*next = temp->next;
if (temp->processed)
{
if (prev == NULL)
*head = temp->next;
else
prev->next = temp->next;
char file_to_delete[50] = { NULL };
memcpy_s(file_to_delete, strlen(temp->filename), temp->filename, strlen(temp->filename));
DeleteFileA(file_to_delete);
free(temp);
}
else
{
prev = temp;
}
temp = next;
} while (temp != first);
if (prev == NULL)
{
return NULL;
}
return *head;
}

Binary tree not adding strings from file

#include <stdio.h>
#include <stdlib.h>
struct treeNode
{
char *word;
int NumberCnt;
struct treeNode *rightPTR, *leftPTR;
};
typedef struct treeNode node;
node *rootPTR = NULL;
void freeTree(node *currPTR)
{
if (currPTR!= NULL)
{
freeTree(currPTR -> leftPTR);
free(currPTR);
freeTree(currPTR -> rightPTR);
}
}
void printTree(node *currPTR)
{
if (currPTR != NULL)
{
printTree(currPTR ->leftPTR);
printf("%s appeared:%d times\n", currPTR->word, currPTR->NumberCnt);
printTree(currPTR ->rightPTR);
}
}
int insertNode (char* input)
{
node *tempPTR = malloc(sizeof(node));
tempPTR -> word = input;
tempPTR -> NumberCnt=0;
tempPTR -> leftPTR = NULL;
tempPTR -> rightPTR = NULL;
if (rootPTR == NULL)
{
rootPTR = tempPTR;
rootPTR -> NumberCnt++;
}
else
{
node *currPTR = rootPTR;
node *prevPTR = NULL;
while (currPTR != NULL)
{
int comp = strcmp(input, (currPTR->word));
if (comp == 0)
{
printf ("Entry already exists\n");
currPTR->NumberCnt++;
return 1;
}
else if (comp < 0)
{
prevPTR = currPTR;
currPTR = currPTR->leftPTR;
}
else if (comp > 0)
{
prevPTR = currPTR;
currPTR = currPTR->rightPTR;
}
}
int comp = strcmp(input, (prevPTR ->word));
if (comp < 0)
{
prevPTR->leftPTR = tempPTR;
prevPTR ->NumberCnt++;
}
else if (comp > 0)
{
prevPTR->rightPTR = tempPTR;
prevPTR->NumberCnt++;
}
return 0;
}
printf("root1%s\n",rootPTR->word);
return 2;
}
int search(char* input)
{
if (input == rootPTR ->word)
{
printf("Node found %s\n", rootPTR->word);
return 0;
}
else
{
if (input < rootPTR ->word)
{
node *currPTR = rootPTR->leftPTR;
while (currPTR != NULL)
{
if (input == currPTR->word)
{
printf("Node found %s\n", currPTR->word);
return 0;
}
else if (input < currPTR->word)
{
currPTR = (currPTR -> leftPTR);
}
else if (input > currPTR->word)
{
currPTR = (currPTR -> rightPTR);
}
}
printf ("Node not in tree\n");
return 1;
}
if (input > rootPTR ->word)
{
node *currPTR = rootPTR->rightPTR;
while (currPTR != NULL)
{
if (input == currPTR->word)
{
printf ("Node found %s\n", currPTR->word);
return 0;
}
else if (input < currPTR->word)
{
currPTR = (currPTR -> leftPTR);
}
else if (input > currPTR->word)
{
currPTR = (currPTR ->rightPTR);
}
}
printf ("Node not in tree\n");
return 1;
}
}
return 2;
}
void fixWord(char* buff)
{
char* unfixed = buff;
char* fixed = buff;
while (*unfixed)
{
if (isalpha(*unfixed))
{
*fixed=tolower(*unfixed);
*fixed++;
}
*unfixed++;
}
*fixed=0;
}
int main()
{
FILE *ptr_file;
char buff [100];
//ptr_file = fopen ("sherlock.txt", "r");
ptr_file = fopen ("input.txt", "r");
if (!ptr_file)
printf("File read error");
while(fscanf(ptr_file, "%s ", buff ) != EOF)
{
int comparison = strcmp(buff, "endoffile");
if (comparison == 0)
{
return 0;
}
fixWord(buff);
insertNode(buff);
}
fclose(ptr_file);
printf("root:%s\n", rootPTR->word);
return 0;
}
Ok I have this binary tree which is taking string inputs from a file. It works if I pass strings directly to the tree, however when I attempt to pass it the strings I read in form the file it keeps on replacing the root node and does not add them correctly to the tree.
buff is current line value and overwritten on each line reading:
insertNode(buff);
insertNode assigns overwriten buffer.
int insertNode (char* input)
{
node *tempPTR = malloc(sizeof(node));
tempPTR -> word = input;
....
So, you should dynamic allocation for input value as:
int insertNode (char* input)
{
node *tempPTR = malloc(sizeof(node));
tempPTR -> word = strdup(input);
....
You're passing buff to your insert function, and it's storing that in the node. So all your nodes will end up pointing to the same address, that of buff in main.
You need to allocate storage for each string in each node, and copy your input into that. And remember to deallocate properly when you delete your tree.
strdup can be handy for that if your library has it.

Encountering segment fault when printing out directories in Ubuntu

I've been working on this code for a while and I can not figure out the problem. The idea is to print out all directories and sub directories from the given directory (hard coded for testing purposes). However, I keep getting a segmentation fault.
#include <stdio.h>
#include <dirent.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
struct item
{
char location[256];
int level;
int order;
bool isExpanded;
struct item *next;
};
struct item *headNode = NULL;
struct item *currentNode = NULL;
struct item *loopNode = NULL;
static int currentLevel = 1;
static int currentOrder = 1;
bool finished = false;
char currentLocation[256];
void addNode(char location[256])
{
struct item *ptr = (struct item*)malloc(sizeof(struct item));
ptr->level = currentLevel;
ptr->order = currentOrder;
ptr->isExpanded = false;
int x;
for(x = 0; x < strlen(location); x++)
ptr->location[x] = location[x];
ptr->location[x] = '\0';
ptr->next = NULL;
currentNode->next = ptr;
currentNode = ptr;
}
int main(int argc, char *argv[])
{
struct dirent *pDirent;
DIR *pDir;
argv[1] = "/home/collin/Documents";
char temp[256];
pDir = opendir (argv[1]);
if (pDir == NULL)
{
printf ("Cannot open directory '%s'\n", argv[1]);
return 1;
}
closedir (pDir);
headNode = (struct item*)malloc(sizeof(struct item));
headNode->level = currentLevel;
headNode->order = currentOrder;
headNode->isExpanded = false;
int x;
for(x = 0; x < strlen(argv[1]); x++)
{
headNode->location[x] = argv[1][x];
currentLocation[x] = argv[1][x];
}
headNode->location[x] = '\0';
currentLocation[x] = '\0';
headNode->next = NULL;
currentNode = headNode;
while(!finished)
{
finished = true;
loopNode = headNode;
currentLevel++;
currentOrder = 1;
while(loopNode != NULL)
{
if(!loopNode->isExpanded)
{
pDir = opendir (loopNode->location);
for (x = 0; x < strlen(loopNode->location); x++)
{
currentLocation[x] = loopNode->location[x];
}
currentLocation[x] = '\0';
while ((pDirent = readdir(pDir)) != NULL)
{
finished = false;
if(!(!strcmp(pDirent->d_name, ".")||!strcmp(pDirent->d_name, "..")))
{
sprintf(temp, "%s/%s", currentLocation, pDirent->d_name);
addNode(temp);
currentOrder++;
}
}
closedir (pDir);
loopNode->isExpanded = true;
}
loopNode = loopNode->next;
}
}
currentNode = headNode;
while (currentNode != NULL)
{
printf ("%d:%d:%s\n", currentNode->level, currentNode->order, currentNode->location);
currentNode = currentNode->next;
}
return 0;
}
You're not checking that opendir's parameter is a directory, and trying to call it on files too. Either check opendir return value, or check that file you requesting to open is actually a directory, or - even better - both.

Resources