Encountering segment fault when printing out directories in Ubuntu - c

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.

Related

CS50 "Speller": Problem with dictionary file

I'm working on CS59 Week 5's "Speller" assignment. Currently, I'm trying to write the unload function with a test dictionary file on my desktop. But for some reason, line 91 (while(!feof(dictionary))) is returning an error:
"request for member '_flag' in something not a structure or a union"
I'm working from a new computer. My previous computer did not return this error. Can someone please explain what's going on here and how I can fix it? Thanks in advance.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
unsigned int HASH_MAX = 50;
unsigned int LENGTH = 20;
unsigned int hash (const char *word);
bool load(char *dictionary);
bool check (char *word);
bool unload (void);
void print (void);
typedef struct _node
{
char *word[20];
struct _node *next;
} node;
node *HASH_TABLE[50];
int main(int argc, char *argv[])
{
FILE *dictionary = fopen("C:/Users/aaron/Desktop/Dictionary.txt", "r");
if(!dictionary)
{
printf("FILE NOT FOUND\n");
return 1;
}
if (load(dictionary))
{
// print "LIST (number): {(name, address), ...}\n
print();
}
int lois = hash("Lois");
printf("\n%s\n", HASH_TABLE[lois]->word);
if (check("StEwIe"))
{
printf("STEWIE found\n");
}
else if (!check("StEwIe"))
{
printf("STEWIE not found\n");
}
if (check("Tron"))
{
printf("TRON found\n");
}
else if (!check("Tron"))
{
printf("TRON not found\n");
}
if (unload())
{
print();
}
}
unsigned int hash(const char *word) // hash code function (FIND A BETTER ALGORITHM)
{
char word_conv[LENGTH + 1]; // store converted word for uniform key
unsigned int code = 0; // hash code
for (int i = 0; i < strlen(word); i++) // set all letters in the word to lower case
{
word_conv[i] = tolower(word[i]);
}
for (int j = 0; j < strlen(word_conv); j++) // for all letters in converted word, add ascii value to code and multiply by 3
{
code += word_conv[j];
code *= 3;
}
code = code % HASH_MAX; // set code to remainder of current code divided by maximum hash table size
return code;
}
bool load (char *dictionary)
{
char word[LENGTH+1];
while(!feof(dictionary))
{
fscanf(dictionary, "%s", word);
node *new_n = malloc(sizeof(node));
strcpy(new_n->word, word);
new_n->next = NULL;
unsigned int code = hash(word);
if (HASH_TABLE[code] == NULL)
{
HASH_TABLE[code] = new_n;
}
else if (HASH_TABLE[code] != NULL)
{
node *trav = HASH_TABLE[code];
while (trav->next != NULL)
{
trav = trav->next;
}
if (trav->next == NULL)
{
trav->next = new_n;
}
}
}
return true;
}
bool check (char *word)
{
unsigned int code = hash(word);
node *check = malloc(sizeof(node));
check = HASH_TABLE[code];
while (check != NULL)
{
if (strcasecmp(check->word, word) == 0)
return true;
}
if (check == NULL)
return false;
}
bool unload (void)
{
for (int i = 0; i < HASH_MAX; i++)
{
while (strcmp(HASH_TABLE[i]->word, "FREE" != 0)
{
node *curr = HASH_TABLE[i];
node *prev = NULL;
while (curr != NULL)
{
prev = curr;
curr = curr->next;
}
strcpy(prev->word, "FREE");
}
}
return true; // freed successfully
}
void print (void)
{
for (int i = 0; i < HASH_MAX; i++)
{
node *check = HASH_TABLE[i];
printf("LIST %02d: {", i);
while (check != NULL)
{
printf("%s, ", check->word);
check = check->next;
}
printf("}\n");
}
}

How to sort lines of a file alphabetically in C? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
Ok so what I have right now, checks the counts of the words. But I am having trouble trying to sort the words alphabetically.
I'd rather do that then just count the number of which they are.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node *node_ptr;
typedef struct node {
int count;
char *word;
node_ptr next;
} node_t;
char *words[] = { "hello", "goodbye", "sometimes", "others", "hello", "others", NULL };
node_ptr new_node() {
node_ptr aNode;
aNode = (node_ptr)(malloc(sizeof(node_t)));
if (aNode) {
aNode->next = (node_ptr)NULL;
aNode->word = (char *)NULL;
aNode->count = 0;
}
return aNode;
}
node_ptr add_word(char *word, node_ptr theList) {
node_ptr currPtr, lastPtr, newPtr;
int result;
int found = 0;
currPtr = theList;
lastPtr = NULL;
printf("Checking word:%s\n", word);
if (!currPtr) {
newPtr = new_node();
if (!newPtr) {
fprintf(stderr, "Fatal Error. Memory alloc error\n");
exit(1);
}
newPtr->word = word;
newPtr->next = currPtr;
newPtr->count = 1;
found = 1;
theList = newPtr;
}
while (currPtr && !found) {
result = strcmp(currPtr->word, word);
if (result == 0) {
currPtr->count += 1;
found = 1;
} else
if (result>0) {
newPtr = new_node();
if (!newPtr) {
fprintf(stderr, "Fatal Error. Memory alloc error\n");
exit(1);
}
newPtr->word = word;
newPtr->next = currPtr;
newPtr->count = 1;
if (lastPtr) {
lastPtr->next = newPtr;
} else {
theList = newPtr;
}
found = 1;
} else {
lastPtr = currPtr;
currPtr = currPtr->next;
}
}
if ((!found) && lastPtr) {
newPtr = new_node();
if (!newPtr) {
fprintf(stderr, "Fatal Error. Memory alloc error\n");
exit(1);
}
newPtr->word = word;
newPtr->next = (node_ptr)NULL;
newPtr->count = 1;
lastPtr->next = newPtr;
found = 1;
}
return theList;
}
void printList(node_ptr theList) {
node_ptr currPtr = theList;
while (currPtr) {
printf("word: %s\n", currPtr->word);
printf("count: %d\n", currPtr->count);
printf("---\n");
currPtr = currPtr->next;
}
}
int main() {
char **w = words;
node_ptr theList = (node_ptr)NULL;
printf("Start\n");
while (*w) {
theList = add_word(*w, theList);
w++;
}
printList(theList);
printf("OK!\n");
return 0;
}
I'd also like to instead of reading from an array of words, I'd rather read from a file.
FILE *fp;
fp = fopen("some.txt", "w");
How do I read from a file using my structure I've created and then sort them?
You can read the words from a file with fscanf():
int main(int argc, char *argv[]) {
node_t *theList = NULL;
for (int i = 1; i < argc; i++) {
FILE *fp = fopen(argv[i], "r");
if (fp != NULL) {
char word[100];
while (fscanf(fp, "%99s", word) == 1) {
theList = add_word(word, theList);
}
fclose(fp);
}
}
printList(theList);
printf("OK!\n");
return 0;
}

Trying to delete all the elements from HashTable with the status marked as closed

#include<iostream>
using namespace std;
enum Stare {DESCHIS=10, LUCRU=20, DUPLICAT=30, REZOLVAT=40, INCHIS=50};
struct Task
{
char *idTask;
char *data;
char *numeInginer;
int nivelComplexitate;
Stare stare;
};
struct List
{
Task *task;
List*next;
};
struct HashTable
{
List** vector;
int size;
};
List* creareNodLista(Task *task)
{
List*nod = (List*)malloc(sizeof(List));
nod->task = task;
nod->next = NULL;
return nod;
}
void initHashTable(HashTable &hTable, int size)
{
hTable.vector = (List**)malloc(sizeof(List*)*size);
hTable.size = size;
memset(hTable.vector, 0, sizeof(List*)*size);
}
int fhash(char c, int l)
{
return c%l;
}
void inserareNodLista(List*&list, List*nod)
{
nod->next = list;
list = nod;
}
void inserareNodHashTable(HashTable hTable, List*nod)
{ //determinarea pozitiei pe care se face inserarea
int index = fhash(nod->task->numeInginer[0],hTable.size);
//obtinerea listei in care se face inserarea
List*list = hTable.vector[index];
//inserare element nou in lista
inserareNodLista(list, nod);
//actualizare element in hashTable
hTable.vector[index] = list;
}
List* getHashTable(HashTable ht, char cheie)
{
int f = fhash(cheie, ht.size);
return ht.vector[f];
}
void printHashTable(HashTable ht)
{
for (char c = 'A'; c < 'Z'; c++)
{
List*lista = getHashTable(ht, c);
int count = 0;
while (lista)
{
count++;
printf("%d", count);
printf("%s\n", lista->task->idTask);
printf("%s\n", lista->task->data);
printf("%s\n", lista->task->numeInginer);
printf("%d\n", lista->task->nivelComplexitate);
printf("%d\n", lista->task->stare);
lista = lista->next;
}
if (count>1)
printf("\nColiziune\n\n");
}
}
int stergeNodHashTable(HashTable hTable, char*numeInginer)
{
int pozitie = 0;
pozitie = fhash(numeInginer[0], hTable.size);
if (hTable.vector[pozitie] == NULL)
return -1;
else
{
if (strcmp(hTable.vector[pozitie]->task->numeInginer, numeInginer) == 0)
{
if (hTable.vector[pozitie]->next == NULL)
{
free(hTable.vector[pozitie]->task->idTask);
free(hTable.vector[pozitie]->task->data);
free(hTable.vector[pozitie]->task->numeInginer);
free(hTable.vector[pozitie]->task);
free(hTable.vector[pozitie]);
hTable.vector[pozitie] = NULL;
}
else
{
List*lista = hTable.vector[pozitie];
hTable.vector[pozitie] = lista->next;
free(lista->task->idTask);
free(lista->task->data);
free(lista->task->numeInginer);
free(lista->task);
free(lista);
lista->next = NULL;
lista = NULL;
}
}
else
{
List*tmp = hTable.vector[pozitie];
while (tmp->next != NULL && strcmp(tmp->next->task->numeInginer, numeInginer) != 0)
tmp = tmp->next;
List*list = tmp->next;
if (list->next == NULL)
{
free(list->task->idTask);
free(list->task->numeInginer);
free(list->task->data);
free(list->task);
free(list);
tmp->next = NULL;
list = NULL;
}
else
{
List*tmp = list;
list = list->next;
free(tmp->task->idTask);
free(tmp->task->data);
free(tmp->task->numeInginer);
free(tmp->task);
free(tmp);
tmp->next = NULL;
tmp = NULL;
}
}
}
return pozitie;
}
void main()
{
FILE *pFile = fopen("Text.txt", "r");
Task *task = NULL;
HashTable ht;
initHashTable(ht, 29);
if (pFile)
{
while (!feof(pFile))
{
task = (Task*)malloc(sizeof(Task));
char id[50];
fscanf(pFile, "%s", &id);
task->idTask = (char*)malloc(strlen(id) + 1);
strcpy(task->idTask, id);
char data[50];
fscanf(pFile, "%s", data);
task->data = (char*)malloc(strlen(data) + 1);
strcpy(task->data, data);
char numeInfiner[50];
fscanf(pFile, "%s", numeInfiner);
task->numeInginer = (char*)malloc(strlen(numeInfiner) + 1);
strcpy(task->numeInginer, numeInfiner);
fscanf(pFile, "%d", &task->nivelComplexitate);
fscanf(pFile, "%d", &task->stare);
//creare element lista
List*nod = creareNodLista(task);
//inserare element in hashTable
inserareNodHashTable(ht, nod);
}
fclose(pFile);
for (char c = 'A'; c < 'Z'; c++)
{
List *lista = getHashTable(ht, c);
while (lista)
{
if (lista->task->stare == 50)
stergeNodHashTable(ht, lista->task->numeInginer);
}
}
printHashTable(ht);
}
}
I am trying to delete from hashTable all the elements with status marked as closed. The delete function is working fine but when i call it for al the hashtable, it got me error: lista->task was 0xDDDDDD. I cant understand why. Please help me!

List of lists C

I want to make list made of lists and the inner list is made of items.
Union of datatype:
typedef union s_datatype {
int t_int;
char* t_char;
double t_double;
bool t_bool;
} t_datatype;
Structure of item:
typedef struct s_token {
int y;
int type;
t_datatype value;
struct s_token *next;
} t_token;
Structure of inner list:
typedef struct s_line {
int x;
int depth;
int type;
int number_of_tokens;
t_token*head;
struct s_line *next;
} t_line;
Structure of the final list:
typedef struct s_tokenized_code {
int number_of_lines;
t_line*head;
} t_tokenized_code;
Let's say that I want to add new "line" and into that line, I want to insert the "token". But I don't know, how to put this together. Can you help me? I'm not sure how to alloc this and how to work with this list of lists.
EDIT: Structure modified
Solved.
If you want to know, how to (i want to insert items to the end of list, not beginning):
t_token*init_token (int y, int type, t_datatype value) {
t_token*token = malloc(sizeof(struct s_token));
if (token == NULL) {
return NULL;
}
token->y = y;
token->type = type;
token->value = value;
token->next = NULL;
return token;
}
t_line*init_line (int x, int depth, int type) {
t_line*line = malloc(sizeof(struct s_line));
if (line == NULL) {
return NULL;
}
line->x = x;
line->depth = depth;
line->type = type;
line->number_of_tokens = 0;
line->head = NULL;
line->next = NULL;
return line;
}
t_tokenized_code*init_code (void) {
t_tokenized_code*code = malloc(sizeof(struct s_tokenized_code));
if (code == NULL) {
return NULL;
}
code->number_of_lines = 0;
code->head = NULL;
return code;
}
void insert_token (t_line*line, t_token*token) {
if (token != NULL) {
if (line->head == NULL){
line->head = token;
line->number_of_tokens += 1;
return;
}
t_token*tmp = line->head;
while (tmp->next != NULL) {
tmp = tmp->next;
}
tmp->next = token;
line->number_of_tokens += 1;
}
}
void insert_line (t_tokenized_code*code, t_line*line) {
if (line != NULL) {
if (code->head == NULL) {
code->head = line;
code->number_of_lines += 1;
return;
}
t_line*tmp = code->head;
while (tmp->next != NULL) {
tmp = tmp->next;
}
tmp->next = line;
code->number_of_lines += 1;
}
}
void free_code (t_tokenized_code*source) {
if (source == NULL) {
return;
}
t_line*line;
t_token*token;
while ((line = source->head) != NULL) {
while ((token = line->head) != NULL) {
line->head = token->next;
free(token);
}
source->head = line->next;
free(line);
}
free(source);
}
Let's make a simple test - Adding 2 tokens to the first line and 3 tokens to the second line:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main (void) {
t_tokenized_code*source = init_code();
t_line*line = init_line(0,0,3);
if (line == NULL) {
return 1;
}
insert_line(source, line);
t_datatype tt;
tt.t_char = "first";
t_token*token = init_token(0,6, tt);
if (token == NULL) {
return 1;
}
insert_token(line, token);
tt.t_char = "second";
token = init_token(1,6, tt);
insert_token(line, token);
line = init_line(1,0,3);
insert_line(source, line);
tt.t_char = "third";
token = init_token(0,6, tt);
insert_token(line, token);
tt.t_char = "fourth";
token = init_token(1,6, tt);
insert_token(line, token);
tt.t_char = "fifth";
token = init_token(2,6, tt);
insert_token(line, token);
line = source->head;
while (line != NULL) {
printf("****\n");
token = line->head;
while (token != NULL) {
printf("%s\n", token->value.t_char);
token = token->next;
}
line = line->next;
}
free_code (source);
return 0;
}
The output will be following:
****
first
second
****
third
fourth
fifth

Why am I getting a Segmentation Fault here?

#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <stdlib.h>
typedef struct pr_struct{
int owner;
int burst_time;
struct pr_struct *next_prcmd;
} prcmd_t;
static prcmd_t *pr_head = NULL;
static prcmd_t *pr_tail = NULL;
static int pending_request = 0;
static pthread_mutex_t prmutex = PTHREAD_MUTEX_INITIALIZER;
int add_queue(prcmd_t *node)
{
pthread_mutex_lock(&prmutex);
//code
prcmd_t *curNode = pr_head;
if(pr_head == NULL) { pr_head = node; return;}
while(curNode->next_prcmd)
{
curNode->next_prcmd = (prcmd_t*)malloc(sizeof(prcmd_t));
curNode = curNode->next_prcmd;
}
curNode->next_prcmd = node;
//
pending_request++;
pthread_mutex_unlock(&prmutex);
return(0);
}
int main()
{
if (pr_head == NULL)
{
printf("List is empty!\n");
}
prcmd_t *pr1;
pr1->owner = 1;
pr1->burst_time = 10;
add_queue(pr1);
prcmd_t *curNode = pr_head;
while(curNode->next_prcmd)
{
printf("%i\n", curNode->owner);
curNode = curNode->next_prcmd;
}
}
EDIT:
Here's what I have now...
int main()
{
prcmd_t *pr1;
pr1 = (prcmd_t*)malloc(sizeof(prcmd_t));
pr1->owner = 1;
pr1->burst_time = 10;
if (pr_head == NULL)
{
printf("List is empty!\n");
}
add_queue(pr1);
prcmd_t *curNode = pr_head;
printf("made it here 1\n");
while(curNode->next_prcmd)
{
printf("in the while loop\n");
printf("%i\n", curNode->owner);
curNode = curNode->next_prcmd;
}
}
output is:
List is empty!
made it here 1
pr1 is an uninitialized pointer to prcmd_t struct, dereferencing uninitialized pointer causes undefined behavior.
You need to allocate space for the structure on the heap / stack (depending on where it's gonna be used), so one option is:
// Allocate on stack
prcmd_t pr1;
pr1.owner = 1;
pr1.burst_time = 10;
add_queue(&pr1);
and second is:
//Allocae on heap
prcmd_t *pr1;
pr = (prcmd_t*)malloc(sizeof(prcmd_t));
pr1->owner = 1;
pr1->burst_time = 10;
add_queue(pr1);
Modifying your main method (and main only) to:
int main()
{
if (pr_head == NULL)
{
printf("List is empty!\n");
}
prcmd_t *pr1;
pr1 = (prcmd_t*)malloc(sizeof(prcmd_t));
pr1->owner = 1;
pr1->burst_time = 10;
add_queue(pr1);
prcmd_t *curNode = pr_head;
while(curNode && curNode->owner)
{
printf("%i\n", curNode->owner);
curNode = curNode->next_prcmd;
}
}
Outputs
List is empty!
1
It's hard to tell without you tellung us where...
But
you have to initialize
node->next_prcmd to null
why do you malloc in the while loop? you are
thereby destroing your current->next,
which in the next iteration is pretty
bad...
Mario

Resources