Dynamic stack in C [pop crash] [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
Im making a program to convert a decimal int to binary using a dynamic stack.
It crashes on the last pop.
ex. num: 4 output: 10crash
#include <stdio.h>
struct stack {
struct stack *prev;
int val;
struct stack *next;
};
struct stack *first,*cur,*tmp;
struct stack *GETNODE(){
struct stack *pt = (struct stack *)malloc(sizeof(struct stack));
};
int counter=1;
void push(int val){
tmp=GETNODE();
tmp->prev=NULL;
tmp->val=val;
tmp->next=NULL;
if(first==NULL){
first=tmp;
cur=first;
}else{
tmp->prev=cur;
cur->next=tmp;
cur=tmp;
}
counter++;
};
int pop(){
int val=tmp->val;
cur=tmp->prev;
free(tmp);
tmp=cur;
tmp->next=NULL;
counter--;
return(val);
};
main(){
int num = 4;
while(num!=0){
push(num%2);
num/=2;
}
while(counter!=1){
printf("%d ",pop());
}
}

The problem is in your pop function. If you think about how it operates, in the final pass you will free(tmp), which is currently pointing to the very first item. After you free it, you then assign:
tmp->next=NULL;
You are trying to dereference an invalid pointer at this point.

I made a lot of changes to your code. Mainly, it was far too complicated - only a singly linked list was needed, and you don't need a counter - just track the list pointer. Your GETNODE() function did not return a value, causing undefined behaviour in the calling function. I simplified that too, there is no need for a separate function to allocate memory because malloc() already does that.
#include <stdio.h>
#include <stdlib.h>
struct stack {
struct stack *prev;
int val;
};
struct stack *first = NULL;
void push(int val){
struct stack *pt = malloc(sizeof(struct stack));
if (pt == NULL){
printf ("Bad call to malloc()\n");
exit (1);
}
pt->prev=first;
pt->val=val;
first = pt;
}
int pop(){
int val;
struct stack *pt = first;
if (first == NULL)
return -1;
val=first->val;
first = first->prev;
free(pt);
return(val);
}
void dec2bin(int num){
printf("%-5d", num);
while(num!=0){
push(num%2);
num/=2;
}
while(first){
printf("%d",pop());
}
printf("\n");
}
int main(void){
dec2bin (4);
dec2bin (129);
dec2bin (160);
return 0;
}
Program output:
4 100
129 10000001
160 10100000

I change some part of your code and your code working now.
#include <stdio.h>
#include <stdlib.h>
struct stack {
struct stack *prev;
int val;
struct stack *next;
};
struct stack *first, *cur, *tmp;
int counter = 0;
struct stack *GETNODE()
{
return malloc(sizeof(struct stack));
}
void push(int val)
{
tmp = GETNODE();
tmp->prev = NULL;
tmp->val = val;
tmp->next = NULL;
if (first == NULL) {
first = tmp;
cur = first;
} else {
tmp->prev = cur;
cur->next = tmp;
cur = tmp;
}
counter++;
}
int pop(void)
{
int val = cur->val;
tmp = cur;
cur = cur->prev;
free(tmp);
counter--;
return val;
}
int main(int argc, char *argv[])
{
int num;
scanf("%d", &num);
while (num != 0) {
push(num % 2);
num /= 2;
}
while (counter != 0)
printf("%d ", pop());
printf("\n");
}

Related

Binary Tree Preorder Traversal 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 1 year ago.
Improve this question
I am having a pointer or memory-related problem here:
void nodesVal(struct TreeNode* root, int *returnSize, int **returnArray){
if (root != NULL)
{
*(returnSize) = *(returnSize) + 1;
*returnArray[*(returnSize) - 1] = root->val;
// I get a runtime memory error whenever I try to access ths array
if (root->left != NULL) nodesVal(root->left, returnSize, returnArray);
if (root->right != NULL) nodesVal(root->right, returnSize, returnArray);
}
}
int* preorderTraversal(struct TreeNode* root, int* returnSize){
int *returnArray = (int*)malloc(sizeof(int) * 100);
*returnSize = 0;
nodesVal(root, &returnSize, &returnArray);
return returnArray;
}
Does anyone see where I am going wrong?
Major changes: //-------->
Minor changes: //
#include <stdio.h>
#include <stdlib.h>
struct TreeNode
{
int val;
struct TreeNode *left;
struct TreeNode *right;
};
void nodesVal(struct TreeNode *root, int *returnSize, int **returnArray)
{
if (root != NULL)
{
//-------> (*returnArray)[0] instead of *returnArray[0] ----> [] has higher priority than *
// I changed the order of those two lines so that I don't say size++ and then use size-1 (you can ignore this)
(*returnArray)[*(returnSize)] = root->val;
*(returnSize) = *(returnSize) + 1;
// when you enter this, you already check for NULL, so I removed (if) --- However, this can be ignored
nodesVal(root->left, returnSize, returnArray);
nodesVal(root->right, returnSize, returnArray);
}
}
int *preorderTraversal(struct TreeNode *root, int *returnSize)
{
int *returnArray = (int *)malloc(sizeof(int) * 100);
*returnSize = 0;
// ---------> you were passing &returnSize (int**). However, the function needs (int*). So, pass returnSize
nodesVal(root, returnSize, &returnArray);
return returnArray;
}
void constructNode(struct TreeNode**root,struct TreeNode*left,struct TreeNode* right,int val){
(*root)->left = left;
(*root)->right = right;
(*root)->val = val;
}
int main()
{
struct TreeNode*root = (struct TreeNode*)malloc(sizeof(struct TreeNode));
struct TreeNode*node1 = (struct TreeNode*)malloc(sizeof(struct TreeNode));
struct TreeNode*node2 = (struct TreeNode*)malloc(sizeof(struct TreeNode));
struct TreeNode*node3 = (struct TreeNode*)malloc(sizeof(struct TreeNode));
constructNode(&root,node1,node2,1);
constructNode(&node1,node3,NULL,2);
constructNode(&node2,NULL,NULL,3);
constructNode(&node3,NULL,NULL,4);
int* returnedSize = malloc(sizeof(int));
int* arr = preorderTraversal(root,returnedSize);
for (int i = 0; i < *returnedSize; i++)
{
printf("%d ",arr[i]);
}
printf("\n");
free(arr);
free(returnedSize);
free(root);
free(node1);
free(node2);
free(node3);
return 0;
}

stack implementation - linked list

I'm trying to figure out why my stack struct is not popping the elements and considers the stack to be NULL (i get the else condition from the pop() executing both times)? I'm confused because the printf shows the elements are being added onto to the stack.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int element;
struct node *pnext;
} node_t;
void push(node_t *stack, int elem){
node_t *new = (node_t*) malloc(sizeof(node_t)); // allocate pointer to new node memory
if (new == NULL) perror("Out of memory");
new->pnext = stack;
new->element = elem;
stack = new; // moves the stack back to the top
printf("%d\n", stack->element);
}
int pop(node_t *stack) {
if (stack != NULL) {
node_t *pelem = stack;
int elem = stack->element;
stack = pelem->pnext; // move the stack down
free(pelem); // free the pointer to the popped element memory
return elem;
}
else {
printf("fail");
return 0; // or some other special value
}
}
int main(int argc, char *argv[]){
node_t *stack = NULL ; // start stack as null
push(stack, 3);
push(stack, 5);
int p1 = pop(stack);
int p2 = pop(stack);
printf("Popped elements: %d %d\n", p1, p2);
return 0 ;
}
As said in a remark when you exit push/pop the variable stack in main is unchanged, so it is like you did nothing, except a memory leak in push
To have the new stack in main after a push that function can return the new stack, but this is not possible for pop already returning the poped value, so to have the same solution for both just use give the address of the variable in parameter to the functions to allow to modify it, so a double pointer rather than a simple
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int element;
struct node *pnext;
} node_t;
void push(node_t ** stack, int elem){
node_t *new = (node_t*) malloc(sizeof(node_t)); // allocate pointer to new node memory
if (new == NULL) {
perror("Out of memory");
exit(-1);
}
new->pnext = *stack;
new->element = elem;
*stack = new; // moves the stack back to the top
printf("%d\n", (*stack)->element);
}
int pop(node_t ** stack) {
if (*stack != NULL) {
node_t *pelem = *stack;
int elem = (*stack)->element;
*stack = pelem->pnext; // move the stack down
free(pelem); // free the pointer to the popped element memory
return elem;
}
else {
printf("fail");
return 0; // or some other special value
}
}
int main(int argc, char *argv[]){
node_t *stack = NULL ; // start stack as null
push(&stack, 3);
push(&stack, 5);
int p1 = pop(&stack);
int p2 = pop(&stack);
printf("Popped elements: %d %d\n", p1, p2);
return 0 ;
}
Compilation and execution :
% gcc -Wall s.c
% ./a.out
3
5
Popped elements: 5 3

My code for pre-order traversal of Binary Search Tree is working but how is the stack whose each element is a pointer to the structure working?

This is my code of preorder traversal of BST. It's working fine on Ubuntu. But I don't understand one thing.
In the function iterative_preorder(), I actually wanted a stack to store the pointers to the structure that I defined on the top. I want to know the concept that how is it working. Since, while allocating memory to the stack, I didn't specify anywhere separately that stack should contain size number of pointers to the structure.
Like, when we define:
int stack[size];
We know that stack[1] will be the second block in the stack. But here, I used malloc, which actually just makes one block of the size specified as size * sizeof(node *).
So when the program executes:
stack[++top] = root;
How does the program understand that it has to go to the next pointer to the structure in the stack? I hope my question is clear.
I made another small program, based on the confusion that I had. Here, instead of structure, I used int. I tried to create a stack of size 2, which stores pointers to the integer. Here's the code:
#include <stdio.h>
#include <stdlib.h>
void main() {
int** stack = (int**)malloc(2 * sizeof(int*));
printf("%d", *stack[0]);
}
But this code is throwing segmentation fault (core dumped). As both the codes used the same logic, just that this one used int instead of structure, I don't understand why this is throwing error.
#include <stdio.h>
#include <stdlib.h>
int size = 0;
typedef struct mylist {
int data;
struct mylist *left;
struct mylist *right;
} node;
node *root;
void create_root(node *root) {
root = NULL;
}
//Inserting nodes
node *insert(node *root, int val) {
node *ptr, *parentptr, *nodeptr;
ptr = (node*)malloc(sizeof(node));
ptr->data = val;
ptr->left = NULL;
ptr->right = NULL;
if (root == NULL)
root = ptr;
else {
parentptr = NULL;
nodeptr = root;
while (nodeptr != NULL) {
parentptr = nodeptr;
if (val < nodeptr->data)
nodeptr = nodeptr->left;
else
nodeptr = nodeptr->right;
}
if (val < parentptr->data)
parentptr->left = ptr;
else
parentptr->right = ptr;
}
return root;
}
void iterative_preorder(node *root) {
if (root != NULL) {
int top = -1;
node **stack = (node**)malloc(size * sizeof(node*));
node *cur;
stack[++top] = root;
while (top > -1) {
cur = stack[top--];
printf("%d\t", cur->data);
if (cur->right != NULL)
stack[++top] = cur->right;
if (cur->left != NULL)
stack[++top] = cur->left;
}
}
}
void main() {
int option, val;
node *ptr;
int flag = 1;
create_root(root);
while (flag != 2) {
printf("\nChoose-\n1-Insert\n2-Iterative Preorder Traversal\n3-Exit\n");
scanf("%d", &option);
switch (option) {
case 1: {
printf("\nEnter the value of new node\n");
size++;
scanf("%d", &val);
root = insert(root, val);
}
break;
case 2:
iterative_preorder(root);
break;
case 3:
flag = 2;
break;
default:
printf("\nWrong entry\n");
}
}
}
Your code has a dereference of uninitialized pointer error.
int** stack = (int**)malloc(2*sizeof(int*));
printf("%d",*stack[0]);
In the above code, stack points to an array of two int pointers, what stack[0] points to? it's not initialized.
A live test of your code is available here segfault. you can modify and test it again.

Segmentation Fault (singal 11 sigsegv) with linked list

Was writing a program to practice before with linked lists and pointers before pset5 and am left with two memory errors that i have not been able to remedy.
#include <stdio.h>
#include <stdlib.h>
//define struct for Nodes
typedef struct list
{
int data;
int key;
struct list* next;
}Node;
//function declarations
Node* create(int a, int *counter);
void insert(int a, int *counter);
void delete_list();
void printlist();
//global pointers
Node* Head = NULL;
Node* Current = NULL;
int main()
{
int *keycounter =(int*)malloc(sizeof(int));
int value = 20;
keycounter = 0;
Head=create(value, keycounter);
value = 30;
insert(value, keycounter);
value = 40;
insert(value, keycounter);
printlist();
delete_list();
free(keycounter);
return 0;
}
// VV functions VV
void delete_list()
{
free(Head);
free(Current);
}
Node* create(int a, int *counter)
{
Node* ptr=malloc(sizeof(Node));
if(!ptr)
{
printf("ERROR-NOT ENOUGH MEMORY\n");
free(ptr);
return 0;
}
ptr->data=a;
ptr->key=*counter;
counter++;
return ptr;
}
void insert(int a, int *counter)
{
Node* ptr=malloc(sizeof(Node));
if(!ptr) {
printf("ERROR-NOT ENOUGH MEMORY\n");
free(ptr);
}
ptr->data=a;
ptr->key=*counter;
//point next field to old head
ptr->next=Head;
//assign current node as head of singly linked list
Head=ptr;
counter++;
}
//Thank you guys over at tutorialspoint for this neat idea for testing this.
//https://www.tutorialspoint.com/data_structures_algorithms/linked_list_program_in_c.htm
void printlist()
{
Node* ptr=Head;
printf("TESTING\n");
while(ptr != NULL) {
printf("%p*NODE* KEY:%i VALUE:%i PTR NEXT:%p\n \n", ptr, ptr->key, ptr->data, ptr->next);
ptr=ptr->next;
}
}
Here is my valgrind output:
Still learning so alot of the valgrind output is pretty arcane to me and threads on stack exchange regarding the "signal 11 (SIGSEGV)" error are difficult to comprehend as well.
Also, any tips or advice on my code would be appreciated.
There is a problem in your code. See the below lines:
int main()
{
int *keycounter =(int*)malloc(sizeof(int));
int value = 20;
keycounter = 0; ===> You are setting the pointer to NULL effectively nullifying the effect of your malloc call above
So, in your create function, when you try to access counter, it is leading to NULL pointer dereference
Node* create(int a, int *counter)
{
Node* ptr=malloc(sizeof(Node));
if(!ptr)
{
printf("ERROR-NOT ENOUGH MEMORY\n");
free(ptr);
return 0;
}
ptr->data=a;
ptr->key=*counter; ==> Here it will lead to NULL pointer dereference
If your key member in the struct is just an integer, then no need to pass a pointer (counter is a pointer), you can as well pass an integer and set it.

Segmentation Fault issue, unable to detect [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Can someone help me with this piece of code. I am getting segmentation fault. Kindly help me out as to where I am going wrong.
#include <stdio.h>
#include <stdlib.h>
struct city
{
int x;
int pop;
struct city *next;
};
struct list
{
struct city *head;
};
void insert(struct list *list1,int a,int b)
{
struct city *node = (struct city *)malloc(sizeof(struct city));
node->x=a;
node->pop = b;
if(list1->head!=NULL)
{
node->next=list1->head;
}
list1->head=node;
}
void initialize_list(struct list *list1)
{
list1->head = NULL;
}
void display(struct list *list)
{
struct city *temp = list->head;
while(temp!=NULL)
{
printf("%d %d\n",temp->x,temp->pop);
temp=temp->next;
}
free(temp);
}
void getdata(int *x)
{
char s[1000];
char c;
scanf("%[^\n]%*s",s);
char *p=s;
int i =0;
while(*p!='\0')
{
while(*p==' ' && *p!='\0')
p++;
if(*p!='\0')
x[i] = atoi(p);
while(*p!=' ' && *p!='\0')
p++;
i++;
}
}
int max(int a,int b)
{
if(a>b)
return a;
else
return b;
}
int total(struct list *link)
{
struct city *r1,*r2;
r1=link->head;
r2 = r1;
int S=0;
while(r1!=NULL)
{
r2 = r1;
while(r2!=NULL)
{
S=S+max(r1->pop,r2->pop)*abs((r2->x)-(r1->x));
r2=r2->next;
}
r1=r1->next;
}
printf("\n%d",S);
free(r1);
free(r2);
return S;
}
int main()
{
int T;
int *x,*pop;
int _no_city;
char c;
scanf("%d",&T);
struct list **link = (struct list **)malloc(T*sizeof(struct list*));
for(int i=0;i<T;i++)
{
link[i]=(struct list *)malloc(sizeof(struct list));
}
for(int i =0;i<T;i++)
{
scanf("%d",&_no_city);
x = (int *)malloc(_no_city*sizeof(int));
pop = (int *)malloc(_no_city*sizeof(int));
while((c= getchar()) != '\n' && c != EOF)
fflush(stdin);
getdata(x);
getdata(pop);
initialize_list(link[i]);
for(int j=0;i<_no_city;j++)
{
insert(link[i],x[j],pop[j]);
}
free(x);
free(pop);
}
for(int i=0;i<T;i++)
{
printf("%d",total(link[i]));
}
}
Is the problem lying with my declaring a pointer to pointer, I did that so that I can create an array of pointers of variable length.
There are quite a few bugs in your program, but this one
for(int j=0;i<_no_city;j++)
{
insert(link[i],x[j],pop[j]);
}
will run off the end of x and pop because your loop condition is wrong, and is probably the cause of your crash.

Resources