String is there, but not printed - c

I have quite interesting problem, I guess. I am trying to implement Stack in C. Here is my header and implementation file(I have only implemented Push yet):
my.h:
typedef struct {
char type[3];
int nrOfOpr;
int num;
} BizarreNumber_t;
struct stackNode {
BizarreNumber_t data;
struct stackNode *nextPtr;
};
// stack related
extern void push(struct stackNode *topPtr, BizarreNumber_t info);
my.c:
void push(struct stackNode *topPtr, BizarreNumber_t info){
struct stackNode *newTop = malloc(sizeof(struct stackNode));
struct stackNode oldTop = *topPtr;
newTop->data=info;
newTop->nextPtr=&oldTop;
*topPtr=*newTop;
// printf("topPtr->next->data: %s\n", topPtr->nextPtr->data.type);
//
// printf("oldTop->data: %s\n", oldTop.data.type);
// printf("newTop->data: %s\n", newTop->data.type);
// printf("topPtr->data: %s\n", topPtr->data.type);
}
Lastly This is my main.c:
int main(int argc, char const *argv[]) {
struct stackNode* stackHead=malloc(sizeof(struct stackNode));
BizarreNumber_t a={"sa",1,1};
BizarreNumber_t b={"as",2,2};
stackHead->data=a;
stackHead->nextPtr=NULL;
printf("%s\n", stackHead->data.type);
push(stackHead,b);
printf("%s\n", stackHead->nextPtr->data.type);//HERE!!!
return 0;
}
In main, the line that I wrote "HERE!!!" is not correctly giving true output. Actually it does not give anything. Interesting thing is, whis gives correct output:
printf("%c\n", stackHead->nextPtr->data.type[0]);
I tried to print out every character in string, Results say that String comes main fine. But I cannot see. Why is it so?

stackHead is local variable created in main() function. Whatever modification or changes done with stackHead in push() method won't affect in main() method as it just call by value.
Instead of this pass the address of stackHead to push() method as
push(&stackHead,b); /* pass the address of stackhead */
And change the definition of push() accordingly.
void push(struct stackNode **topPtr, BizarreNumber_t info){
struct stackNode *newTop = malloc(sizeof(struct stackNode));
newTop->data = info;
newTop->nextPtr = *topPtr; /*new node next make it to head node */
*topPtr=newTop; /*update the head node */
}

Related

How to implement a character string in a linked list

The main code itself works fine but I want to make use of character strings instead of the char, and it might be because I've overlooked something absurdly simple. Here is a small snippet of code:
struct Stack
{
char *SData;
int counter;
struct Stack *next;
};
struct Stack* StackNewNode(char SData)
{
struct Stack *stackNode = (struct Stack*)malloc(sizeof(struct Stack));
stackNode->SData = SData; //error here because of the difference of char, should i use []?
stackNode->next = NULL;
return stackNode;
}
void PUSH(struct Stack **root, char SData) //this part only pushes a character
{
struct Stack *stackNode = StackNewNode(SData);
stackNode->next = *root;
*root = stackNode;
printf("\n%c pushed to stack\n", SData);
}
void POP(struct Stack **root)
{
if (*root == NULL)
{
return;
}
struct Stack *temp = *root;
*root = (*root)->next;
char pop = temp->SData; //how should i pop a full string?
free(temp);
printf("%c popped from stack\n", pop);
}
I also want to implement a counter in the Stack. Should i use Stack->counter++ or is there some other more correct way to do it?
Sorry for the wall of text its my first time here
I don't see counter in struct Stack used anywhere in the code snippets you provided. Assuming you want some count of the number of elements in the stack, it wouldn't make sense for this value to be part of the struct. After all, you only need one count, not one attached to every element in the stack. You would want to make this its own variable, perhaps a global defined in the same place as you define root. Just make sure to initialize it to zero.
As for using character strings, you already have char *SData, which can point to a string. All you need to do is change PUSH and StackNewNode to use char* parameter rather than char and then pass it a string, something like this:
PUSH(&root, "My string");
To start with your current code have some type mismatch here: stackNode->SData = SData;
stackNode->SData is a char pointer and SData is a char. I assume your compiler warns you about that - never ignore warnings.
If you want to use C type string you need updates like:
Pass char pointer instead of char
Allocate memory for the string
Copy the passed string to the allocated memory
Free the memory when done
Something like:
struct Stack
{
char *SData;
int counter;
struct Stack *next;
};
struct Stack* StackNewNode(const char* str)
{
struct Stack *stackNode = malloc(sizeof(struct Stack));
if (stackNode == NULL) exit(1);
stackNode->SData = malloc(strlen(str) + 1);
if (stackNode->SData == NULL) exit(1);
strcpy(stackNode->SData, str);
stackNode->next = NULL;
return stackNode;
}
void PUSH(struct Stack **root, const char* str)
{
struct Stack *stackNode = StackNewNode(str);
stackNode->next = *root;
*root = stackNode;
printf("\n%s pushed to stack\n", str);
}
void POP(struct Stack **root)
{
if (*root == NULL)
{
return;
}
struct Stack *temp = *root;
*root = (*root)->next;
printf("%s popped from stack\n", temp->SData);
free(temp->SData);
free(temp);
}
Usage example:
struct Stack *root = NULL;
PUSH(&root, "Hello World");
Adding a counter
In your code you have placed int counter; inside every stack element. You can make that work but I would prefer two structs. One struct type holding information about the whole stack and another struct type for the elements.
Like:
struct StackNode
{
char *SData;
struct StackNode *next;
};
struct Stack
{
int counter;
struct StackNode *root;
};
The functions would need some updates like:
void PUSH(struct Stack *stack, const char* str)
{
struct StackNode *stackNode = StackNewNode(str);
stackNode->next = stack->root;
stack->root = stackNode;
++stack->counter; // Increment counter
printf("\n%s pushed to stack\n", str);
}
Usage example:
struct Stack stack = {0, NULL};
PUSH(&stack, "Hello World");

Segmentation fault when reading from stack

This is my first time creating stacks. I'm quite clear at what I must do, but am quite discouraged by the code not working.
It runs fine till I try to retrieve any data from the root, which immediately results in a segfault.
Here's my program:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct stackNode
{
char letter;
struct stackNode * next;
};
int size=0;
int capacity=10;
struct stackNode * root=NULL;
void push(char data, struct stackNode * root)
{
if(size==capacity)
{
printf("Error: Stack Overflow\n");
return;
}
struct stackNode * new=(struct stackNode *)malloc(sizeof(struct stackNode *));
new->letter=data;
new->next=root;
printf("%c,%u", new->letter, new->next);
root=new;
printf("%c,%u", new->letter, new->next);
size++;
}
char pop(struct stackNode ** root)
{
if(size==0)
{
printf("Error: Stack is Empty\n");
return '\0';
}
printf("\npop*\n");
char temp;
printf("\n*\n");
struct stackNode * tempad;
printf("\n*\n");
temp=(*root)->letter;
printf("\n*\n");
tempad=*root;
printf("\n*\n");
*root=(*root)->next;
printf("\n*\n");
free(tempad);
printf("\n*\n");
size--;
return temp;
}
int main()
{
push('c', root);
push('v', root);
push('n', root);
printf("%c %c %c", pop(&root), pop(&root), pop(&root));
}
Here's the output:
pop*
*
*
Segmentation fault
Could someone point out the mistake?
The main issue is usage of unnecessary global variables which seem to be causing confusion. In push, the parameter is of type struct stackNode * yet it's being manipulated as if it referred to the global root. But root = new is purely local and has no impact on the global root. However, size++ does impact the global scope. This corrupts the stack's logical state, and your error handler at the beginning of pop thinks that size == 3 and doesn't complain. The function then dutifully dereferences root, crashing the program.
A correct stack class should not use global data. It should encapsulate all necessary state in structs. This makes it reusable, enabling creation of multiple stacks (a property I'd want in most classes I'm using).
A few other suggestions:
Avoid side effects where possible. Prints are OK for temporary debugging purposes but should be completely separated from program logic otherwise.
If you are planning on writing error handlers, print to stderr and avoid magic values like return '\0'; that might be mistaken for actual node data.
Don't cast the result of malloc. This can suppress errors and is visually noisy.
Hardcoding capacity feels pretty arbitrary. I'm not sure there's any point to having this (but if there is, add it to the struct). If there's too much metadata about the stack inside each node (ideally, there should be none), create a Stack struct to contain this metadata and point it to the actual stackNode chain.
Another stack design point: malloc/free are slow. For character data, a simple array with a top pointer will be faster and simpler to implement. You can amortize allocation calls with periodic doubling the array when top >= capacity and contracting when top < capacity / 2.
Here's a quick re-write (without the suggestion for the Stack wrapper struct or the array):
#include <stdio.h>
#include <stdlib.h>
struct stackNode {
char letter;
struct stackNode *next;
int size;
};
void push(char data, struct stackNode **root) {
struct stackNode *new = malloc(sizeof(*new));
new->size = *root ? (*root)->size + 1 : 1;
new->letter = data;
new->next = *root;
*root = new;
}
char pop(struct stackNode **root) {
if (!*root || !(*root)->size) {
fprintf(stderr, "pop from empty stack\n");
exit(1);
}
char popped = (*root)->letter;
struct stackNode *cull = *root;
*root = (*root)->next;
free(cull);
return popped;
}
int main() {
struct stackNode *root = NULL;
push('c', &root);
push('v', &root);
push('n', &root);
while (root) {
printf("%c ", pop(&root));
}
puts("");
return 0;
}
This is really confusingly written code (i.e globals with the same name as variables in the local scope). I'm just going to rewrite it, untested and on mobile but should be fine. You can diff to see the issue(s). For one thing though you're setting local variable root to the newest allocation rather than global root.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct stackNode
{
char letter;
struct stackNode* prev;
};
stackNode* kTailStack = NULL;
void push(char data)
{
stackNode* p=(stackNode *)malloc(sizeof(stackNode));
p->letter=data;
p->prev=kTailStack;
kTailStack = p;
}
char pop()
{
stackNode* prev_tail = kTailStack;
char n = 0;
if (prev_tail != NULL)
{
n = prev_tail->letter;
kTailStack = prev_tail->prev;
free(prev_tail);
}
return n;
}
int main()
{
push('c', kTailStack);
push('v', kTailStack);
push('n', kTailStack);
printf("%c %c %c", pop(kTailStack), pop(kTailStack), pop(kTailStack));
}

Adding elements to linked list inside a linked list in C

I'm trying to create a small list for each element in a main list. I have the main list working fine but I don't know how to access and add elements to the small list.
struct smallList
{
char data;
struct smallList *next;
};
struct bigList
{
char data;
struct bigList *next;
struct smallList *head;
} *root;
When I add stuff to the main list, I declare for each new node:
newNode->head = NULL;
I use this function to get the current pointer to an element in main list:
struct bigList *pointer = getPointer(root, value);
Then, to add stuff to its smallList| using that pointer. I pass alongpointer->head` to this function. And its not working.
insert(pointer->head, value)
As WhozCraig suggests, you can resolve your problem using a pointer to a pointer. Something like this:
void insert(struct smallList **head, char value)
{
*head = newSmallList(value, *head);
}
newSmallList would be something like:
struct smallList *newSmallList(char value, struct smallList *rest)
{
struct smallList *result = malloc(sizeof(struct smallList));
result->next = rest;
result->data = value;
return result;
}
The problem with your current setup is that you are passing the value of the pointer->head field (which happens to be null) to the function, when what you want is to alter what is stored in the field. Here is a program using integers that illustrates a similar mistake:
void setFive(int i)
{
i = 5;
}
int main(void)
{
int myInt = 7;
setFive(myInt);
printf("%d\n", myInt); /* still 7! */
return 0;
}

Value of struct member changes after printing C

I got this code and a strange behaviour while printing the id member variable of node.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
int id;
int visited;
// struct node *neighbors_[];
};
struct graph
{
struct node nodes[26];
int adjMat[26][26];
};
struct stack_item
{
struct node node;
struct stack_item *next_;
};
struct myStack
{
struct stack_item *anfang_;
};
void initGraph(struct graph *graph_);
void push(struct myStack *stack_, struct node node);
int main()
{
struct graph graph;
struct myStack stack;
char ausgabe[26]="";
initGraph(&graph);
//READ DATA
char line[200];
int firstTime=1,first;
first=0;
push(&stack,graph.nodes[first]);
printf("ID %i\n",stack.anfang_->node.id);
printf("ID %i\n",stack.anfang_->node.id);
//FINISHED DATA READING
//CALL DFS
//dfs(graph,stack,ausgabe);
}
void push(struct myStack *stack_, struct node node)
{
struct stack_item item;
item.node=node;
item.next_=stack_->anfang_;
stack_->anfang_=&item;
}
void initGraph(struct graph *graph_)
{
int i,j;
for(i=0; i<26; i++)
{
struct node node= {i,0};
graph_->nodes[i]=node;
for(j=0; j<26; j++)
{
graph_->adjMat[i][j]=0;
}
}
}
If i execute this, the first print command leads to 'ID 0',the second to 'ID 1980796117'. How can this value change by printing it? Could please anyone help me, i've got really no idea!
void push(struct myStack *stack_, struct node node)
{
struct stack_item item;
item.node=node;
item.next_=stack_->anfang_;
/* BAD! */
stack_->anfang_=&item;
}
item is a local variable which, when the push function returns, goes out of scope. Any existing pointers which refer to this object are now invalid, and dereferencing it results in undefined behavior.
You will need to dynamically allocate item (i.e., malloc) if you need it to persist once the function has returned.

changing struct/variable content in C

I would like to get some help with the following question.
I have a struct Node and I want to change it's insides using some method.
and I want to print the content of the changed struct inside my main method.
how do I get the struct changed and see the changed value in my main without returning the node as a return value.
I guess it might be solved with passing the struct Node as a pointer and then editing it.
what is the right way to do so?
for example:
typedef struct Node{
struct Node * right;
struct Node * left;
void * data;
}Node;
void insert(void * element, Node* root){
if(root==NULL){
root=(Node*)malloc(sizeof(Node));
root->data=element;
}
}
int main(){
Node a;
int b=8;
insert(&b,&a);
printf("%d",*(int*)a.data);
return 0;
}
printf doesn't print 8 it prints 1 (i guess some garbage)
It sounds like you are trying to do the following
Create a struct in one method, say main
Pass it to a second method, say example
Have example modify the struct and have the results visible in main
If so then the way to do this in C is by passing the struct as a pointer to example.
struct Node {
int data;
struct Node* pNext;
};
void example(struct Node* pNode) {
pNode->data = 42;
pNode->pNext = NULL;
}
int main() {
struct Node n;
example(&n);
printf("%d\n", n.data);
}
EDIT
Responding to the updated question.
To see the result of a modification of a Node you must pass a Node*. And accordingly to see the result of a Node* modification you need to pass a Node**. Essentially you need to pass one more level of indirection than the value you want to mutate / return.
void insert(void* element, Node** ppRoot){
if (NULL == *ppRoot) {
Node* pTemp = malloc(sizeof(Node));
pTemp->data = element;
*ppRoot = pTemp;
}
}

Resources