Removing even numbers from queue - c

I got stuck when trying to remove even number from queue in C programming. Here is the code:
void deleteEven(Queue *que)
{
while (!isEmptyQueue(que)) {
if ((que->list.first->data) % 2 == 0) {
dequeue(que->list.first->data);
}
}
}
int dequeue(Queue *que)
{
int x;
if (que->list.first!= NULL) {
x= ((que->list).first)->data;
remove(&que->list, 0);
que->list.size--;
return x;
}
else return NULL;
}
What I am trying to do is first, I tried to check if the queue is empty. Then I will get the linked list head and modulus with 2, if getting 0 means it's even number and then I will dequeue it from the queue.
However, with these code, when I try to dequeue even numbers from queue, it just stopped working and not showing any error message.
Anybody know how to solve this? Thanks in advance.

Based on your edited edition and my imagination of the remove() function and the enqueue() function, I think what you really need is like following.
void deleteEven(Queue *que)
{
Queue *odd =(Queue*) malloc(sizeof(Queue));
odd->list.size = 0;
odd->list.first = NULL;
while (!isEmptyQueue(que)) {
if ((que->list.first->data) % 2 != 0) {
enqueue(odd, que->list.first->data);
}
//dequeue(que->list.first->data); wrong
dequeue(que); // passing the queue to dequeue function, not an integer
}
while (!isEmptyQueue(odd)) {
enqueue(que, odd->list.first->data);
dequeue(odd); // simply do dequeue on odd
}
free(odd);
}
Because there is not any error message or crash happen, I assume the bug is caused by the your misuse of dequeue function which didn't dequeue at all.

void deleteEven(Queue *que)
{
Queue newq;
newq.List.first = NULL;
newq.List.size = 0;
while (!isEmptyQueue(que))
{
if ((que->list.first->data) % 2 != 0)
{
enqueue(newq, que->list.first->data);
}
dequeue(que);
}
while (!isEmptyQueue(newq))
{
enqueue(que, dequeue(newq));
}
}

Related

C: Bus Error between function returns and execution goes back to parent function

To simplify the problem as much as possible, I have two functions, a parent that calls the child. Everything executes okay till it gets to the return of the child function. After that I get a Bus Error.
int main () {
game();
// this doesn't get executed and program fails with bus error
printf("Execute 2");
return 1;
}
int game () {
game_t GameInfo = {.level = 1, .score = 0, .playerCh = 0, .playerX = 1, .playerY = 1};
gameLevel(&GameInfo);
mvprintw(1,1, "Executed");
// code works up to here and get's executed properly
return 1;
};
void gameLevel (game_t *GameInfo) {
// determine the size of the game field
int cellCols = COLS / 3;
int cellRows = (LINES / 3) - 2;
GameInfo -> playerX = 1;
GameInfo -> playerY = 1;
generateMaze(0);
int solved = 0;
int level = GameInfo -> level;
// default player position
getPlayerDefault(GameInfo);
pthread_t enemies_th;
pthread_create(&enemies_th, NULL, enemies, (void *)GameInfo);
// enemies(&level);
while (solved == 0 && GameInfo -> collision != 1) {
printGameInfo(GameInfo);
noecho();
char move = getch();
echo();
if (GameInfo -> collision != 1) {
if (checkMoveValidity(move, GameInfo) == 1) {
solved = movePlayer(move, GameInfo);
if (solved == 1) {
break;
}
}
} else {
break;
}
}
if (solved == 1) {
pthread_cancel(enemies_th);
GameInfo->level++;
gameLevel(GameInfo);
} else {
// game over
pthread_cancel(enemies_th);
return;
}
}
Now, the code is much more complicated than here, but I think that shouldn't have any influence on this (?) as it executes properly, until the return statement. There is also ncurses and multithreading, quite complex custom structures, but it all works, up until that point. Any ideas ?
Tried putting print statements after each segment of code, everything worked up until this.
pthread_cancel() doesn't terminate the requested thread immediately. The only way to know that a cancelled thread has terminated is to call pthread_join(). If the thread is left running, it will interfere with use of the GameInfo variable in the next level of the game if the current level is solved, or may use the GameInfo variable beyond its lifetime if the current level was not solved and the main thread returns back to the main() function.
To make sure the old enemies thread has terminated, add calls to pthread_join() to the gameLevel() function as shown below:
if (solved == 1) {
pthread_cancel(enemies_th);
pthread_join(enemies_th);
GameInfo->level++;
gameLevel(GameInfo);
} else {
// game over
pthread_cancel(enemies_th);
pthread_join(enemies_th);
return;
}
The use of tail recursion in gameLevel() seems unnecessary. I recommend returning the solved value and letting the game() function start the next level:
In game():
while (gameLevel(&GameInfo)) {
GameInfo.level++;
}
In gameLevel():
int gameLevel(game_t *GameInfo) {
/* ... */
pthread_cancel(enemies_th);
pthread_join(enemies_th);
return solved;
}

FIFO queue for Producer Consumer Problem Not Working

I currently am trying to implement FIFO for the producer consumer problem. However when I run the code it seems that the first item is not being removed from the buffer as the output shows that every consumer is consuming the first item and never the others (Screenshot of output attached).
I implemented a LIFO queue and got the expected result which is what leads me to believe that the issue is with my FIFO implementation.
Simple error in dequeue. Imagine you want to get the first entry in the queue ( buffer_rd == 0). But you increment buffer_rd and the read theat entry,
buffer_t dequeuebuffer() {
if (buffer_rd == buffer_wr) {
printf("Buffer underflow\n");
} else {
buffer_rd = (buffer_rd + 1) % SIZE; <<<<<====
return buffer[buffer_rd]; <<<<<<======
}
return 0;
}
you need to reverse those 2 (like in insert)
buffer_t dequeuebuffer() {
if (buffer_rd == buffer_wr) {
printf("Buffer underflow\n");
} else {
int ret = buffer[buffer_rd];
buffer_rd = (buffer_rd + 1) % SIZE;
return ret;
}
return 0;
}

C function that creates a linked list with "divisible by 3" numbers from another linked list

First, I need to create and show a list that ends with number 1000. That works well.
Then, I want to create another list with only the numbers that are divisible by 3 in the first list, but it doesn't work.
The worst thing is that it doesn't even tell me what's going on. It just gives error in the execution but the console doesn't say anything.
I will really appreciate any help.
I tried all.
#include <stdio.h>
#include <stdlib.h>
#include<time.h>
#define CANTIDAD_NUMEROS 13
#define CANTIDAD_NUMEROS2 6
#define DESDE 1
#define HASTA 10
typedef struct lista{
int num;
struct lista *sig;
}nodo;
void crear (nodo *pt, int, int);
void crear2 (nodo *pt, int, nodo *pt2);
void mostrar(nodo *pt);
int main()
{
int i=0;
int t=0;
nodo *prin;
nodo *prin2;
prin=(nodo*)malloc(sizeof(nodo));
prin2=(nodo*)malloc(sizeof(nodo));
crear(prin,i, t); //creates first list
mostrar (prin); //shows first list
crear2(prin,i, prin2); //gets 'divisible by 3' numbers
mostrar(prin2); // shows second list
return 0;
}
//creates list
void crear (nodo *registro, int cont, int t)
{
scanf("%d", &t);
registro->num = t;
if (registro->num == 1000)
registro->sig=NULL;
else
{
registro->sig=(nodo*)malloc(sizeof(nodo));
cont++;
crear (registro->sig,cont, t);
}
return;
}
//shows list
void mostrar (nodo *registro)
{
if (registro->sig !=NULL)
{
printf ("%d\n",registro->num);
mostrar (registro->sig);
}else{
printf("%d\n",registro->num);
}
return;
}
//creates second list with only numbers that are divisible by 3
void crear2 (nodo *registro, int cont, nodo *registroNuevo)
{
if ((registro->num % 3) == 0){
registroNuevo->num = registro->num;
registroNuevo->sig = (nodo*)malloc(sizeof(nodo));
}
if(registro->sig != NULL){
crear2(registro->sig,cont, registroNuevo->sig);
}else{
return;
}
}
I expect to have the 1st list shown (which it's happening) and also the 2nd list shown with the numbers that are divisible by 3, which doesn't happen.
First of all, I admire your dedication to recursion!
The problem is that in crear2, registroNuevo->sig is uninitialized which causes a segfault. I almost always start a function that operates on a recursive linked data structure by checking if the parameter node is null. If so, I can safely continue on with the body of the function. Following this logic of protecting against nulls, we need to pass the registroNuevo node along without touching it in the case when registro->num % 3 != 0 and ensure all of its fields are initialized.
Here's the corrected function:
void crear2(nodo *registro, int cont, nodo *registroNuevo)
{
if (registro) {
if (registro->num % 3 == 0) {
registroNuevo->num = registro->num;
registroNuevo->sig = NULL;
if (registro->sig) {
registroNuevo->sig = malloc(sizeof(nodo));
}
crear2(registro->sig, cont, registroNuevo->sig);
}
else {
crear2(registro->sig, cont, registroNuevo);
}
}
}
Having said that, this function is still a bit less than ideal for a couple reasons. First of all, the name is vague and could describe the behavior better. Also, if there are no items divisible by three, you've got a malloced node back in the calling scope that never gets initialized, so it's a bit brittle in that regard. Thirdly, even with a parameter, it feels like a highly specific function without much reusability factor that could be written iteratively inside the calling scope like:
#include <stdio.h>
#include <stdlib.h>
typedef struct nodo
{
int num;
struct nodo *sig;
} nodo;
nodo *crear(nodo *registro, int num)
{
nodo *n = malloc(sizeof(nodo));
n->num = num;
n->sig = registro;
return n;
}
void mostrar(nodo *registro)
{
if (registro)
{
printf("%d->", registro->num);
mostrar(registro->sig);
}
else puts("");
}
void free_lista(nodo *registro)
{
if (registro)
{
free_lista(registro->sig);
free(registro);
}
}
int main()
{
nodo *prin = NULL;
nodo *prin_div_3 = NULL;
for (int t; scanf("%d", &t) && t != 1000;)
{
prin = crear(prin, t);
}
nodo *tmp = prin;
while (tmp)
{
if (tmp->num % 3 == 0)
{
prin_div_3 = crear(prin_div_3, tmp->num);
}
tmp = tmp->sig;
}
mostrar(prin);
mostrar(prin_div_3);
free_lista(prin);
free_lista(prin_div_3);
return 0;
}
This isn't perfect--without tail nodes, adding to the list is a bit less than ideal, but dangling heads are eliminated, and hopefully it shows an alternate approach to organizing program logic and functions.
A few other remarks:
Always free memory that you've allocated. You can write a simple recursive routine to do so, like free_lista as shown in the above example.
Consider avoiding highly specific functions with hard-coded values like 3 and 1000. Make these parameters to maximize reusability.
crear2 never uses the cont member, and you have global constants that are unused. It's a good idea to clean these up to help clarify your debugging efforts and reduce visual clutter.
No need to cast the result of malloc.
if (registro->sig !=NULL) as the first line of a function is going to crash on a null. You don't need != NULL either. if (registro) { ... } is clearest and avoids problems with null parameters.
void crear2 (nodo *registro, int cont, nodo *registroNuevo) {
if ((registro->num % 3) == 0) {
registroNuevo->num = registro->num;
registroNuevo->sig = (nodo*)malloc(sizeof(nodo));
if (registro->sig != NULL)
crear2(registro->sig, cont, registroNuevo->sig);
}
else {
if (registro->sig != NULL)
crear2(registro->sig, cont, registroNuevo);
}
}
This is my approach, but you are still getting a final unexpected 0 at the last mostrar() call; and you still need to do the 'free' calls. I think you should avoid the recursive calls, there are easier ways to do it. Saludos.

pointers and linked list in C- unexpected behavior of program

I recently started programming in C, and I've been working in a linked list program for a while. Now, the program is about having a profile in which you will register movies you watch and then save them in a .txt file. the trouble comes with the movie getting into the list. when I try to print it, the fields will show empty, as if I weren't assigning the pointers properly, but the fact is that the program KNOWS that I stacked a movie in my profile. I know it's a hard question to ask, any help would be appreciated. I'll show here the Insertmovie function, where I think there might be the problem, and the moviecopy function(I tested that function and does not work itself, although I doubt I did something wrong there):
int stacknewmovie (movie* p, list* l){
if(!p || !l){
return 0;
}
node* n;
n=newnode();
if(!n){
return 0;
}
insertnodeinfo(n, p);
n->next=NULL;
if(l->first==NULL){
l->first=n;
return 1;
}else{
n->next=l->first;
l->first=n;
return 1;
}
}
Here the moviecopy:
int moviecopy(movie* pel2,movie* pel1){
if(!pel1 || !pel2){
return NULL;
}else{
pel2=pel1;
return 1;
}
}
Again, thanks for taking your time. I didn't know how to show my problem better, as the compiler doesn't even warns me about anything.
node* insertnodeinfo(node* n, movie* p){
if(!p || !n){
return NULL;
}else{
moviecopy(n->info, p);
return n;
}
}
int stacknewmovie (movie* p, list* l){
if(!p || !l){
return 0;
}
node* n;
n=newnode();
if(!n){
return 0;
}
insertnodeinfo(n, p);
n->next=NULL;
if(l->first==NULL){
l->first=node; //problem here replace "node" by "n"??
return 1;
}else{
n->next=l->first;
l->first=n;
return 1;
}
as I did in the comment replace "node" by "n" first (I suppose that you want to write "n" not "node")
I think it is not a linked list because:
n->next=l->first; //this made the list a circular linked list
l->first=n; //Here is the problem I think
Because always the new node becomes the first node in the list, Is this that you want?

Sorting algorithm for a Dynamic Array in C

I am trying to sort a Dynamic Array that contains Costs as elements. This is my sorting function:
void ascending_sort(Controller* ctrl) //the function is in the controller
{
int i,j;
DynamicVector* CostList=getAll(ctrl->repo); //the getALL function returns the CostList that has Costs as elements
for(i=0;i<getLen(CostList)-1;i++)
{
Cost* cost=(Cost*)getElementAtPosition(CostList,i); //getElementAtPosition returns the Cost at a certain position
for(j=i+1;j<getLen(CostList);j++)
{
Cost* cost1=(Cost*)getElementAtPosition(CostList,j);
if(cost->sum > cost1->sum)
{
Cost aux=cost[i];
cost[i]=cost[j];
cost[j]=aux;
}
}
}
}
The problem is when I want to print the costs. If I print them before sorting, everything goes right and prints the costs. If I sort the list and then print the sorted Costs I get a "Close Program" error, and the program crashes.
This is the print function:
void PrintCosts(Console* console)
{
DynamicVector* CostList=getAllCosts(console->ctrl);
if (getLen(CostList))
{
int i;
for(i=0;i<getLen(CostList);i++)
{
printf("\nCost %d\n\n",i+1);
Cost *c=(Cost*)getElementAtPosition(CostList,i);
PrintCost(c);
}
}
else printf("No cost in the list!");
}
This is the struct:
typedef struct{
int id;
char* day;
char* type;
int sum;
}Cost;
This is the sorting function that is called in the console:
void AscendingSort(Console* console)
{
ascending_sort(console->ctrl);
}
This is a function that returns a Cost* type:
Cost* initCost(char* day, char* type, int sum)
{
Cost* c=(Cost*)malloc(sizeof(Cost));
if(strlen(day)>0 && strlen(day)<=10)
{
c->day = copyString(day);
}
else
{
c->day=0;
}
if(strlen(type)>0 && strlen(type)<=20)
{
c->type = copyString(type);
}
else
{
c->type=0;
}
if(sum>0)
{
c->sum= sum;
}
return c;
}
Console:
Console* initConsole(Controller* ctrl)
{
Console* console=(Console*)malloc(sizeof(Console));
console->ctrl=ctrl;
return console;
}
getElementAtPosition
TElem getElementAtPosition(DynamicVector* v, int pos)
{
if(v->elem[pos])
return v->elem[pos];
else
return 0;
}
typedef void* TElem;
You are trying to access cost as array, in sort code
Cost aux=cost[i];
cost[i]=cost[j];
cost[j]=aux;
which is not correct, assuming getElementAtPosition() return pointer to one item and not the array of items which are sequentially accessible i.e array.
You can only access one element through pointer notification like cost->sum and not cost[i].sum unless i==0.
Sounds like you're getting a segfault. You haven't shown the functions that return the Cost* and you never validate the Cost* before dereferencing it. Maybe something's wrong in that area? I think I'd need some more source code to verify that.
Also I noticed this.
for(i=0;i<getLen(CostList);i++)
{
printf("\nCost %d\n\n",i+1);
Cost *c=(Cost*)getElementAtPosition(CostList,i); <-- typeof(C) == Cost*
PrintCost(c); <-- typeof(C) == Console*
}
You're using the variable c as both a Cost* and a Console*. This isn't a typesafe way of doing things, so I'm guessing you have some errors here. Can't tell without more code though :)

Resources