Issue Initializing Double Stacked linked lists in C - c

I am coding a data structure involving a set of two linked lists, stacked on top of each other. When trying to initialize the set in my test harness, I get a segmentation error. I've commented out all value setters to test to see if I could figure out the error myself, but I could not.
Prototype for init method:
Test Harness:
int
main( )
{
list the_list;
int used = 0;
int values[MAX_VALUES];
char input[LINE_LEN];
char command;
int argument;
int num_found;
bool result;
set_t lower;
set_t upper;
the_list->lower = lower;
the_list->upper = upper;
input[0] = '\0';
input[LINE_LEN-1] = '\0';
fgets( input, LINE_LEN, stdin );
while (*input != 'q') {
num_found = sscanf( input, "%c %d", &command, &argument );
if (num_found > 0) {
switch (command) {
case 'i':
printf ("Request to initialize the set\n");
if (num_found == 1) {
result = set_init( &the_list );
} else {
result = set_init( NULL );
}
printf ("Returned as %d\n", result);
break;
34,0-1 8%
Init method:
bool
set_init( list *the_list )
{
bool initialized = false;
if (the_list !=NULL ) {
/* We have space to initialize. */
the_list->lower->set_size = 0;
/* the_list->lower->head = NULL;
the_list->lower->tail = NULL;
the_list->lower->set_level = 1;
the_list->lower->ready = true;
the_list->upper->set_size = 0;
the_list->upper->head = NULL;
the_list->upper->tail = NULL;
the_list->upper->set_level = 2;
the_list->upper->ready = true;*/
initialized = true;
}
return initialized;
}
Also my struct definitions for my set, linked list, and node structs:
typedef struct _set_node_t {
test_type_t *data;
struct _set_node_t *next;
struct _set_node_t *below;
} set_node_t;
/* the set itself keeps track of the head and the tail of the linked list */
typedef struct {
int set_size;
bool ready;
set_node_t *head;
set_node_t *tail;
int set_level;
} set_t;
typedef struct {
set_t *lower;
set_t *upper;
}list;

The only thing that could be crashing here is this line:
the_list->lower->set_size = 0;
Either the_list or the_list->lower must be uninitialized or NULL or be pointing to invalid or inaccessible memory.
Edit: Yeah this line will crash because you don't initialize the_list.lower:
result = set_init( &the_list );
And this line will crash because you're passing NULL:
result = set_init( NULL );

Related

Exception thrown: read access violation. **head** was 0xCCCCCCCC. occurred

I am writing a Linked list in C. This is my code. I cannot really see any logic error here but when printing in while loop, after the last node is printed it does not jump out of the loop but keep looping then give me this error "Exception thrown: read access violation. head was 0xCCCCCCCC. occurred" on the "head" pointer in the loop.
// ass0.c
#define _CRT_SECURE_NO_WARNINGS
#define _CRTDBG_MAP_ALLOC // need this to get the line identification
//_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF); // in main, after local declarations
//NB must be in debug build
#include <crtdbg.h>
#include <stdio.h>
#include <string.h>
typedef enum { FALSE = 0, TRUE } BOOL;
struct Frame {
char* frameName;
struct Frame* pNext;
};
typedef struct {
char* animationName;
struct Frame* frames;
}Animation;
// Forward declarations
void InitAnimation(Animation*);
void InsertFrame(Animation*);
//void DeleteFrame(Animation*);
//void EditFrame(Animation*);
void ReportAnimation(Animation*);
//void CleanUp(Animation*);
int main(void)
{
char response;
BOOL RUNNING = TRUE;
Animation RG;
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
InitAnimation(&RG);
while (RUNNING)
{
printf("MENU\n 1. Insert a Frame at the front\n 2. Delete last Frame\n 3. Edit a Frame\n 4. Report the Animation\n 5. Quit\n");
scanf("%c", &response);
switch (response)
{
case '1':InsertFrame(&RG); break;
//case '2':DeleteFrame(&RG); break;
//case '3':EditFrame(&RG); break;
case '4':ReportAnimation(&RG); break;
//case '5':RUNNING = FALSE; CleanUp(&RG); break;
default:printf("Please enter a valid option\n");
}
}
return 0;
}
void InitAnimation(Animation* newAnimation) {
newAnimation = malloc(sizeof(Animation));
newAnimation->animationName = "Animation_1";
newAnimation->frames = NULL;
}
void InsertFrame(Animation* animation) {
printf("Insert a Frame in the Animation\n");
char fName[50];
printf("Please enter the Frame Name: ");
scanf("%s", fName);
struct Frame *newFrame;
newFrame = malloc(sizeof(struct Frame));
int nameSize = strlen(fName);
newFrame->frameName = malloc(nameSize + 1);
strcpy(newFrame->frameName, fName);
newFrame->pNext = 0;
//struct Frame* head;
if (animation->frames == NULL)
animation->frames = newFrame;
//head = animation->frames;
//head->pNext = NULL;
//head = animation->frames;
else {
//head = animation->frames;
newFrame->pNext = animation->frames;
animation->frames = newFrame;
/*while (head != NULL) {
newFrame->pNext = *head;
animation->frames = newFrame;
printf("%s", *head->frameName);
head = head->pNext;
}*/
//head = animation->frames;
printf("\n");
}
}
void ReportAnimation(Animation* animation) {
printf("Animation name is Animation_1\n");
printf("Report the Animation\n");
struct Frame* head = animation->frames;
//printf("%s\n", head->frameName);
while (head) {
printf("%s\n", head->frameName);
head = head->pNext;
}
//printf("%d", count);
}
At least the function InitAnimation does not make sense
void InitAnimation(Animation* newAnimation) {
newAnimation = malloc(sizeof(Animation));
newAnimation->animationName = "Animation_1";
newAnimation->frames = NULL;
}
and hence the program in whole is incorrect.
The original object
Animation RG;
//...
InitAnimation(&RG);
is not initialized. The parameter of the function is just overwritten.
The object of the type Animation is already created in main due to the definition
Animation RG;
You need only to initialize its data members.
Remove the statement with the malloc call
void InitAnimation(Animation* newAnimation) {
newAnimation->animationName = "Animation_1";
newAnimation->frames = NULL;
}
And in general you should allocate dynamically memory for the string that will be pointed to by the data member animationName.
The function cam look the following way
int InitAnimation( Animation *newAnimation, const char *name )
{
newAnimation->animationName = malloc( strlen( name ) + 1 );
int success = newAnimation->animationName !+ NULL;
if ( success )
{
strcpy( newAnimation->animationName, name );
newAnimation->frames = NULL;
}
return success;
}
and called like
Animation RG;
//...
InitAnimation(&RG, "Animation_1" );
Pay attention to that you need to include the header <stdlib.h> where the functions malloc and free are declared.

Pointer disappeared after passing to some functions (even with malloc)

My problem is that I created a pointer at the bottom Main.
Main will call load() to read input from a dictionary and insert the words in a inputfile into a TRIE *dict by calling insert() and getnode(). However, after load() return true, the *dict lost all of the value and I cannot get what I expected(i.e. showing cat is present as it is in my dictionary input file).
I have read from other websites that pointers can retain its value after doing malloc. So I have malloced for the *dict. Please kindly let me know why the value disappeared.
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#define CHAR_TO_INDEX(c) ((int)c - (int)'a')
#define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0])
struct dict
{
char words[46];
struct dict* dictPath[26];
bool isEndOfWord;
};
// Returns new trie node (initialized to NULLs)
struct dict *getNode(void)
{
struct dict *pNode = NULL;
pNode = (struct dict *)malloc(sizeof(struct dict));
if (pNode)
{
int i;
for (i = 0; i < 26; i++)
pNode->dictPath[i] = NULL;
}
return pNode;
}
void insert(struct dict *root, const char *key)
{
int level;
int length = strlen(key);
int index;
struct dict *pCrawl = root;
for (level = 0; level < length; level++)
{
index = CHAR_TO_INDEX(key[level]);
if (!pCrawl->dictPath[index])
{
pCrawl = malloc(sizeof(struct dict));
pCrawl->dictPath[index] = getNode();
}
printf("%i\n",index);
pCrawl = pCrawl->dictPath[index];
}
// mark last node as leaf
pCrawl->isEndOfWord = true;
}
// Returns true if key presents in trie, else false
bool search(struct dict *root, const char *key)
{
int level;
int length = strlen(key);
int index;
struct dict *pCrawl = root;
for (level = 0; level < length; level++)
{
index = CHAR_TO_INDEX(key[level]);
if (!pCrawl->dictPath[index])
{
return false;
}
pCrawl = pCrawl->dictPath[index];
}
return (pCrawl != NULL && pCrawl->isEndOfWord);
}
bool load(struct dict *root, char *inputfile){
// open the dictionary file
FILE *infile = fopen(inputfile,"r");
int dictchar;
char tmpword[46];
int cnt = 0;
root = getNode();
// start iterating to read char
do
{
// read the character
dictchar = fgetc(infile);
if (dictchar != '\n')
{
// assign the dictionary character to a tmpword. tmpword will be used to fit into TRIES later
tmpword[cnt] = dictchar;
cnt ++;
}
// if the character is '\n', fit tmpword into TRIES
else
{
tmpword[cnt] = '\0';
cnt = 0;
for (int i = 0; i < ARRAY_SIZE(tmpword); i++)
insert(root, tmpword);
}
} while (dictchar != EOF);
return true;
}
int main (int argc, char *argv[]){
if (argc != 2)
{
return 1;
}
struct dict *root = malloc(sizeof(struct dict));
load(root, argv[1]);
char output[][32] = {"Not present in trie", "Present in trie"};
printf("%s --- %s\n", "cat", output[search(root, "cat")] );
return 0;
}
p.s. I took reference from https://www.geeksforgeeks.org/trie-insert-and-search/
In you function,
bool load(struct dict *root, char *inputfile)
you pass a root pointer, but then replace it with the result of getNode.
The calling code will not see this change.
You need to pass a pointer to the root pointer,
bool load(struct dict **root, char *inputfile)
for the calling code to see the change.
More simply, since you throw away the root with
root = getNode();
right near the top of the function, you could change the load signature:
struct dict * load(char *inputfile)
Instead of return true; at the end, return root; instead.
You don't have a path returning flase anyway.
Change the calling code too.
Instead of
struct dict *root = malloc(sizeof(struct dict));
load(root, argv[1]);
try this:
struct dict *root = load(argv[1]);

Segmentation fault when using advance function

Hi am trying to create a generic list iterator that stores elements of integer or string.I am trying to test a case where it calls the IteratorG advance(IteratorG it, int n) function which takes in the list it and if n is a positive integer,it advances(moves) towards the first element by n times.If n is negative,it advances towards the last element in the list by n times.The elements are then copied to a newly created list lis and the list returned.If advancing by n times is not possible,the function returns NULL.
This is tested in test case 3 under the test cases below.
However,it is responding with a segmentation fault error and i tried using gdp to diagnose the problem and i suspect it is from the advance function at the line add(lis,&(tem->value));
This is the advance function:
IteratorG advance(IteratorG it, int n){
int zero;
zero=0;
IteratorG lis;
lis = malloc(sizeof (struct IteratorGRep));
assert (lis != NULL);
lis->numofit = 0;
lis->head = NULL;
lis->tail = NULL;
lis->curr = NULL;
Node *tem;
if ((tem = malloc(sizeof(Node))) == NULL) {
return 0;
}
if(n<0 && distanceFromStart(it)!=0 )
{
for(tem=it->curr;n!=zero;it->curr=it->curr->prev)
{
add(lis,&(tem->value));
zero++;
}
return lis;
}
if(n>0 && distanceToEnd(it)!=0)
{
for(tem=it->curr;n!=zero;it->curr=it->curr->next)
{
add(lis,&(tem->value));
zero++;
}
return lis;
}
//To be implemented
//move forward by n times
return NULL;
}
I am using a Linux environment and the errors are indicative from the results. The rest of the functions that are required to test this(test in test case 3 under the test code) should be working fine.Here is the code for the whole program:
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "iteratorG.h"
typedef struct Node {
void *value; // value of thee list item
struct Node *prev;
// pointer previous node in list
struct Node *next;
// pointer to next node in list
// implemented struct here ..
} Node;
typedef struct IteratorGRep {
int numofit; // count of items in list
Node *head; // first node in list
Node *curr; // current node in list
Node *tail; // last node in list
ElmCompareFp cmpElm;
ElmNewFp newElm;
ElmFreeFp freeElm;
// implemented struct here ..
} IteratorGRep;
/*
//Your functions below ....
*/
IteratorG newIterator(ElmCompareFp cmpFp, ElmNewFp newFp, ElmFreeFp freeFp){
IteratorG newit;
if ((newit = malloc(sizeof (struct IteratorGRep)))==NULL)
{
printf("Error...! \n");
}
//assert (newit != NULL);
newit->numofit = 0;
newit->head = NULL;
newit->tail = NULL;
newit->curr = NULL;
newit->cmpElm=cmpFp;
newit->newElm=newFp;
newit->freeElm=freeFp;
return newit;
// implemented function here and changed return value
}
int add(IteratorG it, void *vp){
Node *temp;
if ((temp = malloc(sizeof(Node))) == NULL) {
return 0;
}
Node *tempe;
if ((temp = malloc(sizeof(Node))) == NULL) {
return 0;
}
temp->value = it->newElm(vp);
//temp->next=NULL;
if(it->curr==NULL)
{
//temp->next=it->curr;
it->head=it->tail=temp;
it->curr=temp;
}
else
{
tempe=it->curr;
tempe->prev=temp;
temp->next=tempe;
it->curr=tempe;
it->curr=temp;
it->head=temp;
}
//it->tail=it->head=it->curr;
return 1;
}
int hasNext(IteratorG it){
if(it->curr->next==NULL)
{
return 0;
}
// check if theres next element/node
return 1;
}
int hasPrevious(IteratorG it){
if(it->curr->prev!=NULL)
{
return 1;
}
// check if theres previous element/node
return 0;
}
void *next(IteratorG it){
Node *tempo;
if(it->curr->next==NULL)
{
return NULL;
}
tempo=it->curr;
it->curr=it->curr->next;
// implemented function here
return tempo->value;
}
void *previous(IteratorG it){
Node *tempor;
tempor=it->curr;
if(tempor->prev==NULL)
{
return NULL;
}
tempor=it->curr->prev;
it->curr=it->curr->prev;
//tempor=it->curr;
// move to next node in list
return tempor->value;
}
int del(IteratorG it){
if(it->curr->prev!=NULL)
{
Node *temp_curr=it->curr;
Node *temp_prev=it->curr->prev->prev;
temp_curr->prev=temp_prev;
temp_prev->next=temp_curr;
return 1;
}// delete previous node from list
else
return 0;
}
int set(IteratorG it, void *vp){
if(it->curr->prev!=NULL)
{
it->curr->prev->value=vp;
return 1;
}
// change previous node value with new
return 0;
}
IteratorG advance(IteratorG it, int n){
int zero;
zero=0;
IteratorG lis;
lis = malloc(sizeof (struct IteratorGRep));
assert (lis != NULL);
lis->numofit = 0;
lis->head = NULL;
lis->tail = NULL;
lis->curr = NULL;
Node *tem;
if ((tem = malloc(sizeof(Node))) == NULL) {
return 0;
}
if(n<0 && distanceFromStart(it)!=0 )
{
for(tem=it->curr;n!=zero;it->curr=it->curr->prev)
{
add(lis,tem);
zero++;
}
return lis;
}
if(n>0 && distanceToEnd(it)!=0)
{
for(tem=it->curr;n!=zero;it->curr=it->curr->next)
{
add(lis,&(tem->value));
zero++;
}
return lis;
}
//To be implemented
//move forward by n times
return NULL;
}
void reverse(IteratorG it){
Node *curr = it->head;
Node *temp = NULL;
while(curr != NULL) {
temp = curr->next;
curr->next = curr->prev;
curr->prev = temp;
curr = temp;
}
temp = it->head;
it->head = it->tail;
it->tail = temp;// reverse elements of whole list
}
IteratorG find(IteratorG it, int (*fp) (void *vp) ){
// To be implemented
// Find elements of vp in list after current position and put in new list.return the list.
return NULL;
}
int distanceFromStart(IteratorG it){
Node *c=it->curr;
int count=0;
while(c->prev!=NULL)
{
c=c->prev;
count++;
}
return count;
// count number of elements from start of list to current position
}
int distanceToEnd(IteratorG it){
Node *cu=it->curr;
int count=0;
while(cu->next!=NULL)
{
cu=cu->next;
count++;
}
return count;
// count number of elements from end of list to current position
}
void reset(IteratorG it){
while(it->curr->prev!=NULL)
{
it->curr=it->curr->prev;
}
return;
// move current position to start of list
}
void freeIt(IteratorG it){
assert(it != NULL);
Node *curr, *prev;
curr = it->head;
while (curr != NULL) {
prev = curr;
curr = curr->next;
// free(prev->value);
free(prev);
}
free(it); // free items
}
This is the header file for the code:
#ifndef LISTITERATORG_H
#define LISTITERATORG_H
#include <stdio.h>
typedef struct IteratorGRep *IteratorG;
typedef int (*ElmCompareFp)(void const *e1, void const *e2);
typedef void *(*ElmNewFp)(void const *e1);
typedef void (*ElmFreeFp)(void *e1);
IteratorG newIterator(ElmCompareFp cmpFp, ElmNewFp newFp, ElmFreeFp freeFp);
int add(IteratorG it, void *vp);
int hasNext(IteratorG it);
int hasPrevious(IteratorG it);
void *next(IteratorG it);
void *previous(IteratorG it);
int del(IteratorG it);
int set(IteratorG it, void *vp);
IteratorG advance(IteratorG it, int n);
void reverse(IteratorG it);
IteratorG find(IteratorG it, int (*fp) (void *vp) );
int distanceFromStart(IteratorG it);
int distanceToEnd(IteratorG it);
void reset(IteratorG it);
void freeIt(IteratorG it);
#endif
One of the functions have yet to be implemented and is indicated in the code itself. But I guess that might not be the source of issue here.
EDIT:
heres the test case code. Theres no errors in the test case code just in the program above only :
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "iteratorG.h"
#include "positiveIntType.h"
#include "stringType.h"
#define MAXARRAY 5
/* Helper Functions Below */
/* Returns 1 if marks >= 50, 0 otherwise */
int passMarks(void *marks){
return (*((int *) marks) >= 50);
/* Easy to understand below ..
int *ip = (int *) marks;
if(*ip >= 50) { return 1; }
else { return 0; }
*/
}
/* Returns 1 if str starts with "jo" */
int prefixJo(void *str){
return (strncmp("jo", (char *) str, 2) == 0) ;
}
/* A function to print a string from a void pointer */
void prnStr(void *vp){
assert(vp != NULL);
printf(" %s", (char *) vp );
}
/* A function to print an integer from a void pointer */
void prnInt(void *vp){
assert(vp != NULL);
printf(" %d", *((int *) vp) );
}
/* Prints previous element using the given function 'fp'
examples: prnPrev(it1, prnInt); prnPrev(it2, prnStr);
*/
void prnPrev(IteratorG it, void (*fp) (void *p) ){
void *prevP = previous(it);
assert(prevP != NULL);
printf("> Previous value is: ");
fp(prevP);
printf("\n");
}
/* Prints next element using the given function 'fp'
examples: prnNext(it1, prnInt); prnNext(it2, prnStr);
*/
void prnNext(IteratorG it, void (*fp) (void *p) ){
void *nextP = next(it);
assert(nextP != NULL);
printf("> Next value is: ");
fp(nextP);
printf("\n");
}
/* Prints elements of 'it' from current to last position
using the given function 'fp'. The current position
of 'it' will change to the end of the list.
examples: prnIt(it1, prnInt); prnIt(it2, prnStr);
*/
void prnIt(IteratorG it, void (*fp) (void *p) ){
int count = 0;
while(hasNext(it)){
void *nextP = next(it);
count++;
if(count > 1) { printf(", "); }
fp(nextP);
}
printf("\n");
}
/* Few Tests Below */
void test1(){
printf("\n--==== Test-01 ====------\n");
IteratorG it1 = newIterator(positiveIntCompare, positiveIntNew, positiveIntFree);
int a[MAXARRAY] = { 25, 78, 6, 82 , 11};
for(int i=0; i<MAXARRAY; i++){
int result = add(it1 , &a[i]);
printf("> Inserting %d: %s \n", a[i], (result==1 ? "Success" : "Failed") );
}
freeIt(it1);
printf("--==== End of Test-01 ====------\n");
}
void test2(){
printf("\n--==== Test-02 ====------\n");
IteratorG it1 = newIterator(positiveIntCompare, positiveIntNew, positiveIntFree);
int a[MAXARRAY] = { 72, 14, 62, 8, 93};
for(int i=0; i<MAXARRAY; i++){
int result = add(it1 , &a[i]);
printf("> Inserting %d: %s \n", a[i], (result==1 ? "Success" : "Failed") );
}
prnNext(it1, prnInt);
prnNext(it1, prnInt);
prnPrev(it1, prnInt);
int newVal1 = 55;
int result1 = set(it1, &newVal1);
printf("> Set value: %d ; return val: %d \n", newVal1, result1 );
prnPrev(it1, prnInt);
freeIt(it1);
printf("--==== End of Test-02 ====------\n");
}
void test3(){
printf("\n--==== Test-03 ====------\n");
IteratorG it1 = newIterator(positiveIntCompare, positiveIntNew, positiveIntFree);
int a[MAXARRAY] = { 04, 54, 15, 12, 34};
for(int i=0; i<MAXARRAY; i++){
int result = add(it1 , &a[i]);
printf("> Inserting %d: %s \n", a[i], (result==1 ? "Success" : "Failed") );
}
reset(it1);
printf("> it1 (after reset): \n");
prnIt(it1, prnInt);
reset(it1);
IteratorG advIt1 = advance(it1, 4);
printf("> advance(it1, 4) returns: \n");
prnIt(advIt1, prnInt);
//IteratorG advIt2 = advance(it1, -3);
//printf("> advance(it1, -3) returns: \n");
//prnIt(advIt2, prnInt);
//printf("> In 'it1', ");
//prnPrev(it1, prnInt);
freeIt(it1);
//freeIt(advIt1);
//freeIt(advIt2);
printf("--==== End of Test-03 ====------\n");
}
int main(int argc, char *argv[])
{
test1();
test2();
test3();
return EXIT_SUCCESS;
}

BFS making key list of *char list array, mostly indexing and mallocing

I would like some professional advice for making a char *x array of strings (of const char names with different sizes) Would someone help with mallocing a list to fit the size of a structure name ( qSep->front->name))
Attempt 1: Well my base case works, so I started making multiple print statements. The first one doesn't get put in. My gdb causes error at printf("Found in List %s has name\n", x[0]);
Code and then data structures below.
size_t separation( const User *user1, const User *user2 ) {
int len= 0;
char *x;
//use contains
queueSep *qSep =(struct queueSep*) malloc(sizeof(struct queueSep));
int count = 0;
//pre-condition: the user is not the same as user2
if ( user1->name == user2->name ) { //str compare
return 0;
}
qSep->front = convert(user1, NULL, count);
printf("Conversion complete for %s \n",qSep->front->name);
len++;
x = malloc(len*sizeof((const char*)qSep->front->name));
x[len-1] = qSep->front->name;
printf("Found in List %s has name\n", x[0]);
while( qSep->front != NULL) {
//check if front of the queue is the finish USER
if ( (const char*)qSep->front->name == user2->name ) {
return qSep->front->separationCount;
} else { //add all the neighbours on the queue with separation size incremented
struct node *currAmigo = qSep->front->sepAmigos->amigos_Queue->front;
if ( currAmigo == NULL ) {
//is that a bad thing?
}
while ( currAmigo != NULL ) {
for(int i = 0; i < len; ++i) {
printf("List amigo for %s has name %s\n", currAmigo->data->name, x[i]);
/*
//if(strcmp(x[i], currAmigo->data->name))
{
goto end_nested_loop;
}
*/
}
//make a qSep node
struct sepNode *node = convert(currAmigo->data, NULL, count+1);
len++;
x = realloc(x, len*sizeof(int));
x[len-1] = currAmigo->data->name;
//insert the sepNode into the end of the queue
que_insSepqueue(qSep, node);
//go to Next Amigo in top of Queue
currAmigo=currAmigo->next;
}
end_nested_loop:
count++;
//remove the node
que_deqSep( qSep );
}
}
return -1;
}
Converted Struct
typedef struct sepNode {
const char *name;
struct Friends_struct *sepAmigos;
size_t *separationCount;
struct sepNode *sepNodeNext;
}sepNode;
typedef struct queueSep{
struct sepNode *front; //front of queue
}queueSep;
//How to make a list
typedef struct User_struct {
const char *name;
Friends amigos;
} User;
EXTRA ( to convert a node to say separation length)
sepNode *convert( const User *user1, const User *user2, int count) {
sepNode *sepNode1=
sepNode1 = (struct sepNode*) malloc(sizeof(struct sepNode));
sepNode1->name = user1->name;
sepNode1->sepAmigos = user1->amigos;
sepNode1->separationCount = count;
sepNode1->sepNodeNext = NULL;
return sepNode1;
}
Using a pointer list
char *x;
You have indexes that need to be malloc instead of
x = malloc(len*sizeof((const char*)qSep->front->name));
x[len-1] = qSep->front->name;
Malloc the size of the first index with
x[len-1] = malloc(sizeof(char)*sizeof(qSep->front->name)); //redundant sizeof(char) =1
//just to illustrate
x[len-1] = qSep->front->name;
Also, if anyone knows if I can just free(x); in one line, that would be helpful in a comment.

C Program: Create Linked List Using argv, argc, Segmentation Fault

I have a program that takes in strings using the command line prompts argv and argc. I keep getting a segmentation fault when I go to run the code and after much researching, I cannot determine what might be causing this. Maybe how I execute the code is the issue? I am using gcc -o code code.c then ./code one two three with one two three being the strings added to the linked list. Any assistance in determining where my error might be would be great.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct list_node_s{
char the_char;
struct list_node_s *next_node;
}list_node;
void insert_node(list_node *the_head, char the_char);
void print_list(list_node *the_head);
int main(int argc, char *argv[]){
char next_char;
list_node *the_head = NULL;
insert_node(the_head, next_char);
the_head->next_node = malloc(sizeof(list_node));
if(the_head == NULL){
return 1;
}
the_head->the_char = 1;
the_head->next_node == NULL;
int the_count, the_count2;
for(the_count = 0; the_count < sizeof(argv); the_count++){
for(the_count2 = 0; argv[the_count][the_count2] != '\0'; the_count2++){
next_char = argv[the_count][the_count2];
insert_node(the_head, next_char);
}
}
print_list(the_head);
return (0);
}
void insert_node(list_node *the_head, char the_char){
list_node * current_node = the_head;
while (current_node->next_node != NULL) {
current_node = current_node->next_node;
}
current_node->next_node = malloc(sizeof(list_node));
current_node->next_node->the_char = the_char;
current_node->next_node->next_node = NULL;
}
void print_list(list_node *the_head){
if(the_head == NULL){
printf("\n");
}else{
printf("%c", the_head->the_char);
print_list(the_head->next_node);
}
}
Change this:
list_node *the_head = NULL;
insert_node(the_head, next_char);
the_head->next_node = malloc(sizeof(list_node));
to:
list_node the_head = { '\0', NULL };
to initialize the_head to an empty node.
One problem is in this function:
void insert_node(list_node *the_head, char the_char){
list_node * current_node = the_head;
while (current_node->next_node != NULL) {
current_node = current_node->next_node;
}
current_node->next_node = malloc(sizeof(list_node));
current_node->next_node->the_char = the_char;
current_node->next_node->next_node = NULL;
}
When you call it in main you're basically passing in NULL because you're setting the_head to NULL. You're trying to access current_node->next_node in the while loop conditions, but because of what you're passing in, you're basically doing NULL->next_node.
You need to initialize your head to an empty list_node. Basically since you're using a char as your node element you could set the value of the char to 0x00, which would make it a zero byte. Then that way you know that when you're at that value, you're at the head.
I don't mean to self-promote, but if you want to look at some code for this have a look at this github repo for the Barry_CS-331 Data Structures class. There's C and C++ in there for the Data Structures. I think it might have a list but if not you can use the stack and the queue as an overall example.
I have modified you code, there has some bugs:
1)、the key bug is in this code.
for(the_count = 0; the_count < sizeof(argv); the_count++)
{
for(the_count2 = 0; argv[the_count][the_count2] != '\0'; the_count2++)
{
next_char = argv[the_count][the_count2];
insert_node(the_head, next_char);
}
}
there some bugs:
you cann't use the_count < sizeof(argv), because of the type of argv is char* []; so sizeof(argv) maybe 4 or 8, based on your os.
the right is:
for(the_count = 1; the_count < argc; the_count++){
for(the_count2 = 0; argv[the_count][the_count2] != '\0'; the_count2++){
next_char = argv[the_count][the_count2];
insert_node(the_head, next_char);
}
}
2、this code aose has some bugs:
list_node *the_head = NULL;
insert_node(the_head, next_char);
the_head->next_node = malloc(sizeof(list_node));
if(the_head == NULL){
return 1;
}
the_head->the_char = 1;
the_head->next_node == NULL;
insert_node(the_head, next_char); is no need, you'd better do the_head->the_char = '\0', because of char 1 is no printable character.
One way:
#include <stdio.h>
#include <stdlib.h>
typedef struct list_node_s{
char the_char;
struct list_node_s *next_node;
}list_node;
void insert_node(list_node *the_head, char the_char);
void print_list(list_node *the_head);
int main(int argc, char *argv[]){
list_node *the_head = NULL;
int the_count, the_count2;
for(the_count = 0; the_count < argc; the_count++)
{
for(the_count2 = 0; the_count2 < strlen(argv[the_count]); the_count2++)
insert_node(&the_head, argv[the_count][the_count2]);
}
print_list(the_head);
return (0);
}
void insert_node(list_node **the_head, char the_char){
list_node *new_node;
list_node *tail_node;
/* Allocate and populate a new node. */
new_node = malloc(sizeof(list_node));
new_node->the_char = the_char;
new_node->next_node = NULL;
/* Is the_head already initialized? */
if(*the_head)
{
/* Yes... find the tail_node. */
tail_node = *the_head;
while(tail_node->next)
tail_node = tail_node->next;
/* Append the new_node to the end of the list. */
tail_node->next = new_node;
return;
}
/* the_head was not initialized. The new_node will be the head node. */
*the_head = new_node;
return;
}
void print_list(list_node *the_head){
if(the_head == NULL){
printf("\n");
}else{
printf("%c", the_head->the_char);
print_list(the_head->next_node);
}
}

Resources