Popping stack doesn't work right? (Stack from two queues) - c

I've been stewing over this one for a while, and I can't quite seem to figure out why at execution, when once the following function executes, and the test code in main calls to see if the stack is empty, for some reason it isn't. I can't seem to figure out the exact cause, though I have a feeling it has something to do with the "remove" function not deleting the last node, but for some reason, I can't figure out how to fix it.
TYPE listStackPop (struct Stack* stack)
{
/* FIXME: You will write this function */
assert (stack != NULL);
assert (!listQueueIsEmpty (stack->q1));
return listQueueRemoveFront (stack->q1);
}
---later calls to listQueueRemoveFront---
TYPE listQueueRemoveFront (struct Queue* queue)
{
/* FIXME: You will write this function */
assert (queue != 0);
assert (!listQueueIsEmpty (queue));
struct Link* toDelete;
toDelete = queue->head->next;
if (toDelete == queue->tail) {
queue->tail = queue->head;
}
else {
queue->head->next = toDelete->next;
}
int retVal = toDelete->value;
return retVal;
}
--For clarity, TYPE is defined as int--
I've tried going from simply return toDelete->value to copying toDelete's value to an int, and passing that int to be returned, as I thought maybe toDelete was being removed prematurely or something, but that isn't the case.
Unfortunately, google doesn't really have much info on this either. So far anyway.
Here is the full code on pastebin, in case anyone is interested to read it in full: https://pastebin.com/cDvdHmTu
I had expected it to pass, but for some reason, it failed even though all the other test cases passed.
results:
-------------------------------------------------
---- Testing stack from queue implementation ----
-------------------------------------------------
stack init...
stackIsEmpty == 1: PASSED
pushing 4, 5, -300...
stackIsEmpty == 0: PASSED
popping; val == -300: PASSED
popping; val == 5: PASSED
top val == 4 : PASSED
popping; val == 4: PASSED
stackIsEmpty == 1: FAILED
pushing 0-9...
top val == 9 : PASSED
C:\Users\Zedri\source\repos\Stack From Queues\Debug\Stack From Queues.exe (process 8928) exited with code 0.
Press any key to close this window . . .
Compiler/IDE Used: Visual Studio 2019
-~-~-~Edit 1~-~-~-
removed malloc call to the toDelete pointer
~-~-~-Edit 2-~-~-~
Fixed code on pastebin. Issue resolved.

Never mind, I simply needed to move queue->head->next = toDelete->next; outside of the else block, and remove the else block entirely.

Related

How to implement a 'Pop' function that returns the "popped" element (i.e the data/value) ? (linked list stacks)

Confused as to how to implement a single function that would at the same time pop the element and return it as return value.
So far all I've seen are pop functions that return a pointer to the new head of the stack.
Here's a start, but...
#define VALUE int
typedef struct node_t {
VALUE item;
struct node_t *next;
} node;
.
.
.
// Function
VALUE pop(node *stack_head) {
// Used to store the node we will delete
node *deleteNode = stack_head;
// Error Checking // <<====== (btw, is this actually necessary ?)
if (!deleteNode || !stack_head) {
if (!stack_head) fprintf(stderr, "\nPop failed. --> ...\n");
if (!deleteNode) fprintf(stderr, "\nPop Failed. --> ...\n");
return 0;
}
// Storing the value in a variable
VALUE popped_item = stack_head->item;
// Updating the head
stack_head = stack_head->next; <<====== THERE'S A PROBLEM HERE ! (i think)
// Freeing/Deleting the 'popped' node
free(deleteNode);
// Return 'popped' value
return popped_item;
}
.
.
.
stack_head = stack_head->next;
Doesn't actually change the address that the pointer stack_head (i.e the head of the stack) points to... and so the value is indeed returned for the first pop but subsequent pops return errors.
Yes because it is a local variable but then how would you change the actual pointer (the one that points to the head of the stack) to point to the new head of the stack?
The parameter stack_head is local to the function pop, so when you modify it the result is not visible outside of the function.
You need to pass the address of the variable you want to modify, then in the function you dereference the pointer parameter to change what it points to.
So change your function to this:
VALUE pop(node **stack_head) {
node *deleteNode = *stack_head;
if (!*stack_head) {
fprintf(stderr, "\nPop failed. --> ...\n");
return 0;
}
VALUE popped_item = (*stack_head)->item;
*stack_head = (*stack_head)->next;
free(deleteNode);
return popped_item;
}
And call it like this:
node *stack_head = NULL;
// do something to push onto the stack
VALUE v = pop(&stack_head);
Okay, this will be a pretty long digest, but hopefully worth it. You can see a testcase of the code I've presented as my conclusion here and obtain a modular version of the code here. My suggestion would be that you use a structure like this:
struct {
size_t top;
T value[];
}
The reason you probably shouldn't use classical linked lists for this (or anything, really) is covered by this video courtesy of Bjarne Stroustrup. The basis of the problem is that the majority of your overhead is in allocation and cache misses which don't occur so much when you keep everything in one allocation.
If I were to write this for convenient use, perhaps:
#define stack_of(T) struct { size_t top; T value[]; }
This should allow you to declare empty stacks fairly sensibly, like:
int main(void) {
stack_of(int) *fubar = NULL;
}
This is familiar enough to templates in other languages to work fairly well, and also not a hideous abuse of the preprocessor. I'm sure I've written a push_back function somewhere which we can adapt to this version of push which I've linked to externally as it's not important for the conclusion of this answer (bear with me here; we'll come back to that momentarily)...
So now we have stack_of(T) and push(list, value) which we can use like:
int main(void) {
stack_of(int) *fubar = NULL;
push(fubar, 42);
push(fubar, -1);
}
The simplest solution for pop might be something like:
#define pop(list) (assert(list && list->top), list->value[--list->top]))
... but this does suffer a drawback we'll discuss later. For now we have as a testcase:
int main(void) {
stack_of(int) *fubar = NULL;
int x;
push(fubar, 42);
push(fubar, -1);
x = pop(fubar); printf("popped: %d\n", x);
x = pop(fubar); printf("popped: %d\n", x);
x = pop(fubar); printf("popped: %d\n", x);
}
... and as you'll see during debug the assert fails during execution telling us we've popped more than we've pushed... probably a good thing to have. Still, this doesn't actually reduce the size of the stack. To do that we actually need something more like push again, except we get rid of these lines:
list->top = y; \
list->value[x] = v; \
So there's an opportunity for refactoring. Thus I bring you operate():
#define operate(list, ...) { \
size_t x = list ? list->top : 0 \
, y = x + 1; \
if ((x & y) == 0) { \
void *temp = realloc(list, sizeof *list \
+ (x + y) * sizeof list->value[0]); \
if (!temp) \
return EXIT_FAILURE; \
list = temp; \
} \
__VA_ARGS__; \
}
Now we can redefine push in terms of operate:
#define push(list, v) operate(list, list->value[x] = v; list->top = y)
... and pop looks kind of like it did before, but with an invocation of operate on the end to cause list to shrink (from quadruple its size, for example when you've popped 3 elements off of a list of 4) to no larger than double its size.
#define pop(list) (assert(list && list->top), list->value[--list->top]); \
operate(list, )
Summing it all up, you can see a testcase of the code I've presented here and obtain a modular version of the code here...

Pop consecutive items on a stack if value is the same

For my program I have a stack of strings and I'm trying to pop the value at the top, but if the next string on the stack has the same name I want to pop that one too and so on until all the ones on top with that name are gone. I'm probably butchering the implementation so can someone guide me in the right direction?
char *dropoff(struct stack *tosPtr)
{
printf("current tos is %s\n", tosPtr->name);
if(tosPtr == NULL)
return STACK_IS_EMPTY;
while(strcmp(tosPtr->name, tosPtr->next->name) == 0) {
stack *oldBox = tosPtr;
tosPtr = tosPtr->next;
if(oldBox == tosPtr)
tosPtr = NULL;
free(oldBox);
}
return tosPtr;
}
Looks like you are close. You forgot to remove the first word (you state you want to do this regardless). Then your while is nearly there. Also you are comparing two pointers that should always be un-equal (tosPtr and tosPtr->next) - unless there should be some circular reference you did not mention?
struct stack *dropoff(struct stack *tosPtr) {
printf("current tos is %s\n", tosPtr->name);
if(tosPtr == NULL)
return STACK_IS_EMPTY;
struct stack *oldBox = tosPtr;
tosPtr = tosPtr->next;
//Double check in while we didn't hit bottom of stack
while(tosPtr && strcmp(oldBox->name, tosPtr->name) == 0) {
free(oldBox); //Maybe need to free oldBox->name as well?!
oldBox = tosPtr;
tosPtr = tosPtr->next;
}
//One node left to free - maybe name?
free(oldBox);
return tosPtr ? tosPtr : STACK_IS_EMPTY; //Return empty stack if needed
}
Note you need struct in the variable definition as well if you did not typedef it, and I guess you did not because the argument is defined that way. If the name was mallocd you would need to free it is well before freeing the stack node.

C recursively build tree using structure pointer

I'm now implementing Barnes-Hut Algorithms for simulating N-body problem. I only want to ask about the building-tree part.
There are two functions I made to build the tree for it.
I recursively build the tree, and print the data of each node while building and everything seems correct, but when the program is back to the main function only the root of the tree and the child of the root stores the value. Other nodes' values are not stored, which is weird since I printed them during the recursion and they should have been stored.
Here's some part of the code with modification, which I thought where the problem might be in:
#include<...>
typedef struct node{
int data;
struct node *child1,*child2;
}Node;
Node root; // a global variable
int main(){
.
set_root_and_build(); // is called not only once cuz it's actually in a loop
traverse(&root);
.
}
Here's the function set_root_and_build():
I've set the child pointers to NULL, but didn't show it at first.
void set_root_and_build(){
root.data = ...;
..// set child1 and child2 =NULL;
build(&root,...); // ... part are values of data for it's child
}
And build:
void build(Node *n,...){
Node *new1, *new2 ;
new1 = (Node*)malloc(sizeof(Node));
new2 = (Node*)malloc(sizeof(Node));
... // (set data of new1 and new2 **,also their children are set NULL**)
if(some condition holds for child1){ // else no link, so n->child1 should be NULL
build(new1,...);
n->child1 = new1;
//for debugging, print data of n->child1 & and->child2
}
if(some condition holds for child2){ // else no link, so n->child2 should be NULL
build(new2,...);
n->child1 = new2;
//for debugging, print data of n->child1 & and->child2
}
}
Nodes in the tree may have 1~2 children, not all have 2 children here.
The program prints out the correct data when it's in build() function recursion, but when it is back to main function and calls traverse(), it fails due to a segmentation fault.
I tried to print everything in traverse() and found that only the root, and root.child1, root.child2 stores the value just as what I've mentioned.
Since I have to called build() several times, and even in parallel, new1 and new2 can't be defined as global variables. (but I don't think they cause the problem here).
Does anyone know where it goes wrong?
The traverse part with debugging info:
void traverse(Node n){
...//print out data of n
if(n.child1!=NULL)
traverse(*(n.child1))
...//same for child2
}
You may not be properly setting the children of n when the condition does not hold. You might want this instead:
void set_root_and_build()
{
root.data = ...;
build(&root,...); // ... part are values of data for it's child
}
void build(Node *n,...)
{
n->child1 = n->child2 = NULL;
Node *new1, *new2;
new1 = (Node*) malloc(sizeof(Node));
new2 = (Node*) malloc(sizeof(Node));
// set data of new1 and new2 somehow (read from stdin?)
if (some condition holds for new1)
{
n->child1 = new1;
build(n->child1,...);
//for debugging, print data of n->child1
}
else
free(new1); // or whatever else you need to do to reclaim new1
if (some condition holds for new2)
{
n->child2 = new2;
build(n->child2,...);
//for debugging, print data of n->child2
}
else
free(new2); // or whatever else you need to do to reclaim new2
}
Of course, you should be checking the return values of malloc() and handling errors too.
Also, your traversal is a bit strange as it recurses by copy rather than reference. Do you have a good reason for doing that? If not, then maybe you want:
void traverse(Node *n)
{
...//print out data of n
if (n->child1 != NULL)
traverse(n->child1)
...//same for child2
}
The problem in your tree traversal is that you certainly process the tree until you find a node pointer which is NULL.
Unfortunately when you create the nodes, these are not initialized neither with malloc() nor with new (it would be initialized with calloc() but this practice in cpp code is as bad as malloc()). So your traversal continues to loop/recurse in the neverland of random pointers.
I propose you to take benefit of cpp and change slightly your structure to:
struct Node { // that's C++: no need for typedef
int data;
struct node *child1,*child2;
Node() : data(0), child1(nullptr), child2(nullptr) {} // Makes sure that every created are first initalized
};
And later get rid of your old mallocs. And structure the code to avoid unnecessary allocations:
if(some condition holds for child1){ // else no link, so n->child1 should be NULL
new1=new Node; // if you init it here, no need to free in an else !!
build(new1,...);
n->child1 = new1;
...
}
if (... child2) { ... }
Be aware however that poitners allocated with new should be released with delete and note with free().
Edit: There is a mismatch in your code snippet:
traverse(&root); // you send here a Node*
void traverse(Node n){ // but your function defines an argument by value !
...
}
Check that you didn't overllok some warnings from the compiler, and that you have no abusive cast in your code.

Whether code is read from top to bottom

I am creating a program in c which is based on a linked list, where every node (of struct) holds an integer and a pointer to the next node.
I use dynamic allocation (malloc) and deallocation (free) as new nodes are added and old nodes are deleted.
when a node is deleted a function named delete is called.
I discovered that the program crashes sometimes when this delete-function is called and I KNOW that its something with the pointers in the method but I dont know WHERE in the code (row number) and WHY this happends.
I am used to high-level languages such as Java and I am used to encircle the problem by putting print-syntax at certain places in the method just to reveal WHERE it crashes.
I thought I could do the same with c and with pointer because to my knowledge I beleive the code is read from top to bottom that is 1, 2, 3, 4, and so on. (maybe interrupt handlers behave another way?)
So in this function named delete I have gone so far by putting this printf() at the very beginning of the delete-function - and all the same the program crashes.
So my Question - is it really possible that its some syntax in the delete-function (when I loop pointers for instance) that causes the crash WHEN not even the printf() is printing?
Am I wrong when I believe that the program is executed from to to bottom - that is 1, 2, 3 ....
You can se my printf-function in the very beginning of delete-function
And by the way - how could I solve this problem when I get this cryptic crash message from windows? See the bitmap!!
Greatful for answers!!!
int delete(int data) {
printf("IN THE BEGINNING OF DELETE!!!");
int result = 0;
if (queueref.last != NULL) {
node *curr_ptr;
node *prev_ptr;
node *temp_ptr;
if (queueref.first->data == data) {
temp_ptr = queueref.first;
queueref.first = queueref.first->next;
destroy_node(temp_ptr);
result = 1;
if (queueref.first == NULL) {
queueref.last = NULL;
puts("queue is now empty!!!");
}
} else {
prev_ptr = queueref.first;
curr_ptr = queueref.first->next;
printf("prev_ptr: %d\n", prev_ptr);
printf("curr_ptr: %d\n", curr_ptr);
while(curr_ptr != NULL) {
if (curr_ptr->data == data) {
result = 1;
if (curr_ptr->next != NULL) {
temp_ptr = curr_ptr;
destroy_node(temp_ptr);
prev_ptr->next = curr_ptr->next;
} else {
temp_ptr = curr_ptr;
queueref.last = prev_ptr;
prev_ptr->next = NULL;
destroy_node(temp_ptr);
}
}
curr_ptr = curr_ptr->next;
prev_ptr = prev_ptr->next;
}
}
}
return result;
}
Common mistake, here's the deal. This
printf("IN THE BEGINNING OF DELETE!!!");
needs to be
printf("IN THE BEGINNING OF DELETE!!!\n");
^^ note the newline
The reason is because stdio does not flush stdout until it sees a newline. If you add that newline, you should see the printf when the code enters the function. Without it, the program could crash, the stdout buffer would not have been flushed and would not see the printf.
Your code seems to have lots of implementation flaws. As a general advice I would recommend using some standard well-tested queue support library and static code analyzers (in this case you would even find dynamic analyzer valgrind very helpful, I guess).
For example, if implementation of destroy_node(ptr) is equivalent to free(ptr), then your code suffers from referencing destroyed data (or ,in other words, garbage) in this code snippet:
while(curr_ptr != NULL) {
if (curr_ptr->data == data) {
result = 1;
if (curr_ptr->next != NULL) {
temp_ptr = curr_ptr;
destroy_node(temp_ptr);
prev_ptr->next = curr_ptr->next; //<- curr_ptr is still in stack
//or register, but curr->next
//is garbage
// what if curr_ptr is first node? did you forget to update queueref.first?
} else {
temp_ptr = curr_ptr;
queueref.last = prev_ptr;
prev_ptr->next = NULL;
destroy_node(temp_ptr);
}
// if you you need to destroy only one node - you can leave the loop here with break;
}
curr_ptr = curr_ptr->next; /// assigning garbage again if node is found
prev_ptr = prev_ptr->next;
The reason why using destroyed data can work in * most * (if I can say that, basically this is unpredictable) cases is that the chances that this memory can be reused by other part of program for dynamically allocated data can vary on timings and code flow.
PS
Regarding cryptic messages in the Windows box - when program crashes OS basically generates crashdump and prints registers (and dumps some relevant memory parts). Registers and memory dumps can show the place of crash and immediate register/stack values but you have to now memory map and assembler output to understand it. Crashdump can be loaded to debugger (WinDbg) together with unstripped binary to check stactrace and values of local variables at the moment of crash. All these I described very very briefly, you could find tons of books / guides searching for "windows crash or crashdump analysis"

How to use free on a handle inside a list?-> C -> windows API

I have a list in C that is something like this:
typedef struct _node
{
int number;
DWORD threadID;
HANDLE threadH;
struct *_node next;
} *node;
And you have somthing like this:
node new_node = malloc(sizeof(node));
As you may have guessed out, this list will store information for threads, including their handlers and Id's. Still I am having trouble when I try to do this:
free(new_node);
Everytime I try to do this I encounter an unexpected error, VS saying that there was a data corruption. I've pinned down as much as possible and I found that the problem resides when I try to use free the handle.
I've searched on MSDN how to do this but the only thing I can find is the function that closes the thread (which is not intended here, since I want the thread to run, just deleting it's record from the list).
The question is: how I am supposed to free an handle from the memory? (Considering that this is only a copy of the value of the handle, the active handle is not being deleted).
EDIT: This is the function to insert nodes from the list:
int insereVisitanteLista(node* lista, DWORD threadID, HANDLE threadH, int num_visitante)
{
node visitanteAnterior;
node novoVisitante = (node)malloc(sizeof(node));
if(novoVisitante == NULL)
return 0;
novoVisitante->threadID = threadID;
novoVisitante->threadH = threadH;
novoVisitante->number = num_visitante;
novoVisitante->next = NULL;
if(*lista == NULL)
{
*lista = novoVisitante;
return 1;
}
visitanteAnterior = *lista;
while(visitanteAnterior->next != NULL)
visitanteAnterior = visitanteAnterior->next;
visitanteAnterior->next =novoVisitante;
return 1;
}
And this is the function to delete nodes:
int removeVisitanteLista(node * lista, DWORD threadID)
{
node visitanteAnterior = NULL, visitanteActual;
if(*lista == NULL)
return 0;
visitanteActual = *lista;
if((*lista)->threadID == threadID)
{
*lista = visitanteActual->next;
visitanteActual->next = NULL;
free(visitanteActual);
return 1;
}
while(visitanteActual != NULL && visitanteActual->threadID != threadID)
{
visitanteAnterior = visitanteActual;
visitanteActual = visitanteActual->next;
}
if (visitanteActual == NULL)
return 0;
visitanteAnterior->next = visitanteActual->next;
free(visitanteActual);
return 1;
}
What exactly is a node that you are trying to free? Is this a pointer to a struct _node? If yes, have you allocated it previously? If no, free is not needed, otherwise you have to check if node is not NULL and make sure you do not free it multiple times. It is hard to guess what you are doing and where is an error without a minimal working example reproducing the problem. The only thing I can suggest is to read about memory management in C. This resource might help.
UPDATE:
node in your code is a pointer to _node. So sizeof (node) is a size of a pointer, which is either 4 or 8 bytes (depending on architecture). So you allocate 8 bytes, for example, but assume you have a pointer to the structure which is much larger. As a result, you corrupt memory, and behavior of the program becomes undefined. So changing node novoVisitante = (node)malloc(sizeof(node)) to node novoVisitante = (node)malloc(sizeof(_node)) should fix the problem.
You haven't shown us the context of your call to free() so I need to speculate a little but my first concern is that you didn't mention removing the node from the list before deleting it.
Start by unlinking the node by modifying the next field of the previous (or head) node. If you still get the error, then you have corrupted memory somehow by writing past the end of one of your allocated memory structures or something similar.
Also, I assume node is a pointer. You really haven't provided much information about what you're doing.

Resources