How do you use a typedef struct for a FIFO? - c

I just started programming in C for school. I am being asked to do a program that uses a FIFO struct to resolve math problems. I got the folowing code on the internet for a FIFO, I just don't know how to use it. I tried a lot of things and I can't find anything useful on the internet or maybe that I just don't know the right thing to research but could you please help me? Thanks!
#include <stdio.h>
#include <stdlib.h>
typedef struct pile
{
int donnee;
struct pile *precedent;
} Pile;
void pile_push(Pile **p_pile, int donnee)
{
Pile *p_nouveau = malloc(sizeof *p_nouveau);
if (p_nouveau != NULL)
{
p_nouveau->donnee = donnee;
p_nouveau->precedent = *p_pile;
*p_pile = p_nouveau;
}
}
int pile_pop(Pile **p_pile)
{
int ret = -1;
if (p_pile != NULL)
{
Pile *temporaire = (*p_pile)->precedent;
ret = (*p_pile)->donnee;
free(*p_pile), *p_pile = NULL;
*p_pile = temporaire;
}
return ret;
}
void pile_clear(Pile **p_pile)
{
while (*p_pile != NULL)
{
pile_pop(p_pile);
}
}
I tried doing this:
int main()
{
int return_val;
Pile pile;
pile_push(Pile, 5);
return_val = pile_pop(Pile);
printf(return_val);
}
and got this error:
expected expression before 'Pile'
too few arguments to function 'pile_push'

You have mixed up Pile and pile which is the issue with the first warning. The functions expect a pointer to a pointer to a Pile. That is: They update the value of a pointer, so they need to be passed a reference to a pointer. Your use of printf is also wrong.
int main()
{
int return_val;
Pile *pile = NULL;
pile_push(&pile,5);
return_val = pile_pop(&pile);
printf("return_val is: %d\n",return_val);
}

Related

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.

Freeing memory gives segmentation fault [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 4 years ago.
Improve this question
I've been trying to work with structures, pointers and memory in C.
I have created this structure
typedef struct {
int id;
char *name;
} Object;
here is constructor
void object_ctor(Object *o, int id, char *name)
{
o->id = id;
o->name = malloc(sizeof(name));
if(sizeof(o->name)!=sizeof(name))
{
o->name=NULL;
}
else
{
strcpy(o->name, name);
}
}
here is decleration of o1
char tmp_name[] = "Hello 1";
Object o1;
object_ctor(&o1, 1, tmp_name);
here is destructor
void object_dtor(Object *o)
{
if(o->name != NULL)
{
free(o->name);
o->name = NULL;
}
}
printing object
void print_object(Object *o)
{
printf("ID: %d, NAME: %s\n", o->id, o->name);
}
calling copy
Object copy;
print_object(object_cpy(&copy, &o1));
and I´m trying create a copy of one structure to another (I have already constructed them).
Object *object_cpy(Object *dst, Object *src)
{
if(src!=NULL)
{
const size_t len_str=strlen(src->name)+1;
dst->name = malloc(10000000);
dst->id = src->id;
strncpy (dst->name, src->name,len_str);
}
if (strcmp(dst->name,src->name)!=0)
{
dst->name = NULL;
}
return dst;
}
But then when I'm trying to free both copy and original src I get a segmentation fault. I've been trying to run it through gdb and it said that I'm freeing same memory twice so I assume that the code for copying is wrong, but I don't know where.
And here is code that gives me segmentation fault
printf("\nCOPY EMPTY\n");
object_dtor(&copy);
o1.id = -1;
free(o1.name);
o1.name = NULL;
object_cpy(&copy, &o1);
print_object(&copy);
print_object(&o1);
I´m including these libraries
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
I'm using the std=c99 flag for to compile.
There is at least a problem here:
void object_ctor(Object *o, int id, char *name)
{
o->id = id;
o->name = malloc(sizeof(name));
if (sizeof(o->name) != sizeof(name))
{
o->name = NULL;
}
else
{
strcpy(o->name, name);
}
}
sizeof(name) is not the length of the string pointed by name. You need strlen(name) + 1 (+1 for the NUL terminator).
And your test if (sizeof(o->name) != sizeof(name)) is pointless, and I'm not sure what you're trying to achieve here.
You probably want this:
void object_ctor(Object *o, int id, char *name)
{
o->id = id;
o->name = malloc(strlen(name) + 1);
if (o->name != NULL)
strcpy(o->name, name);
}
There are similar problems in object_cpy:
pointless use of strncpy
pointless allocation of a 10Mb buffer
pointless test strcmp(dst->name, src->name)
You probably want this:
Object *object_cpy(Object *dst, Object *src)
{
if (src != NULL)
{
const size_t len_str = strlen(src->name) + 1;
dst->name = malloc(len_str);
if (dst->name != NULL)
{
dst->id = src->id;
strcpy(dst->name, src->name);
}
}
return dst;
}
With these corrections following code works fine:
int main()
{
char tmp_name[] = "Hello 1";
Object o1, copy;
object_ctor(&o1, 1, tmp_name);
object_cpy(&copy, &o1);
print_object(&copy);
print_object(&o1);
object_dtor(&o1);
object_dtor(&copy);
}
Event if this is not directly an answer to your problem, I'll give you how I organize my code in order to avoid memory problem like yours.
First, it all resolve around a structure.
To each structure, if needed, I do a "Constructor" and a "Destructor".
The purpose of the constructor is simply to set the structure in a coherent state. It can't never fail (implying that any code that could fail, like malloc, should not be in the constructor).
The purpose of the destructor is to clean the structure.
One little trick that I like to use is to put the constructor in a macro, allowing me to do something like 'Object var = OBJET_CONSTRUCTOR'.
Of course, it's not alway possible, it's up to you to be carreful.
For your code, it could be :
typedef struct {
int id;
char *name;
} Object;
#define OBJECT_CONSTRUCTOR {.id = -1,\ \\ Assuming -1 is relevant in your case, like an error code or a bad id value. Otherwise, it's useless.
.name = NULL}
void Object_Constructor(Object *self)
{
Object clean = OBJECT_CONSTRUCTOR;
*self = clean;
}
void Object_Destructor(Object *self)
{
free(self->name);
}
Here we go.
How to use it is simple : You always begin by the constructor, and you alway end by the destructor. That's why it's useless to set the char pointer "name" to NULL in the destructor, because it should not be used after by any other function that the constructor.
Now, you can have "initialisation" function. You can do a plain initialisation (it is your constructor function), or a copy initialisation, etc etc
Just keep in mind that the structure have been called into the constructor. If not, it's the developer fault and you do not have to take that in count.
A behavior that can be nice is, in case of error, to not modify the structure.
Either the structure is entierly modified in succes, or not at all.
For complex structure that can fail at many point, you can do that by "swapping" the result at the end.
void Object_Swap(Object *first, Object *second)
{
Object tmp = OBJECT_CONSTRUCTOR;
tmp = *fisrt;
*first = *second;
*second = tmp;
}
bool Object_InitByPlainList(Object *self, int id, consr char *name)
{
Object newly = OBJECT_CONSTRUCTOR;
bool returnFunction = false;
newly.id = id;
if (!(newly.name = strdup(name))) {
printf("error : %s : strdup(name) : name='%s', errno='%s'.\n", __func__, name, strerror(errno));
goto END_FUNCTION;
}
// Success !
Object_Swap(self, &newly);
returnFunction = true;
/* GOTO */END_FUNCTION:
Object_Destructor(&newly);
return (returnFunction);
}
It may be seem overcomplicated at the first glance, but that organization allow you to add more futur step "that can fail" cleanly.
Now, you can even do something this simply :
bool Object_InitByCopy(Object *dst, Object *src)
{
return (Object_InitByPlainList(dst, src->id, src->name));
}
All you have to do is to say in the documentation :
The first function to be called have to be "Object_Constructor"
After the "Object_Constructor", only the "Object_Init*" function can be called.
The last function to be call have to be "Object_Destructor"
That's all. You can add any "Object_*" function that you whant, like :
void Object_Print(const Object *self)
{
printf("ID: %d, NAME: %s\n", self->id, self->name);
}
Hope this organization will solve your memory problem.
An example :
int main(void)
{
Object test = OBJECT_CONSTRUCTOR;
Object copy = OBJECT_CONSTRUCTOR;
if (!Object_InitByPlainList(&test, 1, "Hello World !")) {
// The function itself has logged why it has fail, so no need to add error printf here
return (1);
}
Object_Print(&test);
if (!Object_Copy(&copy, &test)) {
return (1);
}
Object_Destructor(&test);
Object_Destructor(&copy);
return (0);
}

Dynamic Memory Allocation in C not working

I'm trying to make a game that requires dynamically sized arrays in C but my code isn't working even though identical code works in another one of my programs.
Here are my #includes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SwinGame.h" //API for graphics, physics etc
#include <math.h>
Here are my typedefs for the relevant structs used:
typedef struct position_data
{
double x;
double y;
} position_data;
typedef enum enemy_type_data {CIRCLE, TRIANGLE, SQUARE} enemy_type_data;
typedef struct enemy_data
{
position_data location;
enemy_type_data type;
bitmap bmp;
double health;
double speed;
int path_to;
} enemy_data;
typedef struct enemy_data_array
{
int size;
enemy_data *data;
} enemy_data_array;
Here is the function to add an element to the array:
void add_enemy(enemy_data_array *enemies)
{
enemy_data *new_array;
enemies->size++;
new_array = (enemy_data *)realloc(enemies->data, sizeof(enemy_data) * enemies->size);
if (new_array) //if realloc fails (ie out of memory) it will return null
{
enemies->data = new_array;
// enemies->data[enemies->size - 1] = read_enemy_data();
printf("Enemy added successfully!\n");
}
else
{
printf("FAILED. Out of Memory!\n");
enemies->size--;
}
}
And here is my function call and variable declaration in the main procedure:
int main()
{
path_data my_path[41];
enemy_data_array enemies;
enemies.size = 0;
add_enemy(&enemies);
}
Why isn't this working?
You invoked undefined behavior by passing indeterminate value enemies->data in uninitialized variable having automatic storage duration. Initialize it before using add_enemy().
int main()
{
path_data my_path[41];
enemy_data_array enemies;
enemies.size = 0;
enemies.data = 0; /* add this line */
add_enemy(&enemies);
}
0 is a null pointer constant and can safely be converted to pointer NULL. Unlike NULL, 0 will work without including any headers. Of course you can use enemies.data = NULL; with proper header included.
#2501's explanation is completely correct. Another solution is to change your implementation of add_enemy() to something like this:
void add_enemy(enemy_data_array *enemies)
{
enemy_data *new_array;
// check if size was non-zero
if (enemies->size++)
{
new_array = (enemy_data *)realloc(enemies->data, sizeof(enemy_data) * enemies->size);
}
// start new allocation
else
{
new_array = (enemy_data *)alloc(sizeof(enemy_data) * enemies->size);
}
if (new_array) //if (re)alloc fails (ie out of memory) it will return null
{
enemies->data = new_array;
// enemies->data[enemies->size - 1] = read_enemy_data();
printf("Enemy added successfully!\n");
}
else
{
printf("FAILED. Out of Memory!\n");
enemies->size--;
}
}
If fails because you haven't cleared the content of "enemies". Since it is a stack variable, it will contain whatever garbage data is on the stack.
set enemies.data to NULL in the main function and try it again.

Memory allocation error for structs with members that are function pointers and void pointers

I have written a straightforward C code that uses an engine to run two different algorithms depending on user input. It uses function pointers to the algorithm methods and objects. There is a nasty memory bug somewhere that I can not track down, so maybe I am allocating memory in the wrong way. What is going wrong?
Below is (the relevant parts of) a minimal working example of the code.
main.c
#include "engine.h"
int main()
{
char *id = "one";
Engine_t eng;
Engine_init(&eng);
Engine_select_algorithm(eng, id);
Engine_run(eng);
}
engine.h
typedef struct _Engine *Engine_t;
engine.c
#include "engine.h"
#include "algorithm_one.h"
#include "algorithm_two.h"
typedef struct _Engine
{
void *p_algorithm;
void (*init)(Engine_t);
void (*run)(Engine_t);
} Engine;
void Engine_init(Engine_t *eng)
{
*eng = malloc(sizeof(Engine));
(*eng)->p_algorithm = NULL;
}
void Engine_select_algorithm(Engine_t eng, char *id)
{
if ( strcmp(id, "one") == 0 )
{
eng->init = Algorithm_one_init;
eng->run = Algorithm_one_run;
}
else if ( strcmp(id, "two") == 0 )
{
eng->init = Algorithm_two_init;
eng->run = Algorithm_two_run;
}
else
{
printf("Unknown engine %s.\n", id); exit(0);
}
eng->init(eng);
}
void Engine_run(Engine_t eng)
{
eng->run(eng);
}
void Engine_set_algorithm(Engine_t eng, void *p)
{
eng->p_algorithm = p;
}
void Engine_get_algorithm(Engine_t eng, void *p)
{
p = eng->p_algorithm;
}
algorithm_one.h
typedef struct _A_one *A_one_t;
algorithm_one.c
#include "engine.h"
#include "algorithm_one.h"
typedef struct _A_one
{
float value;
} A_one;
void Algorithm_one_init(Engine_t eng)
{
A_one_t aone;
aone = malloc(sizeof(A_one));
aone->value = 13.0;
//int var = 10;
Engine_set_algorithm(eng, &aone);
}
void Algorithm_one_run(Engine_t eng)
{
A_one_t aone;
Engine_get_algorithm(eng, &aone);
printf("I am running algorithm one with value %f.\n", aone->value);
// The code for algorithm one goes here.
}
The code for algorithm_two.h and algorithm_two.c are identical to the algorithm one files.
There must be a memory bug involved, because the code runs as given, but if I uncomment the
//int var = 10;
line in algoritm_one.c the code crashes with a segmentation fault.
You pass the wrong thing to Engine_set_algorithm. You are passing the address of a local variable rather than the address of the algorithm. You need to write:
Engine_set_algorithm(eng, aone);
And also Engine_get_algorithm is wrong. You are passed a pointer by value and modify that pointer. So the caller cannot see that modification. You need it to be:
void Engine_get_algorithm(Engine_t eng, void **p)
{
*p = eng->p_algorithm;
}
I think your code would be easier if you defined a type to represent an algorithm. That type would be just a void*, but it would make the code much easier to read. What's more, I would make Engine_get_algorithm return the algorithm.
algorithm Engine_get_algorithm(Engine_t eng)
{
return eng->p_algorithm;
}
void Engine_set_algorithm(Engine_t eng, algorithm alg)
{
eng->p_algorithm = alg;
}

Pointer assignment causing program to stall

This is really getting me, I have a program that I'm adding some additional features too, and one thing that I'm trying to do is implement a linked list. First, some code:
#include <stdio.h>
#include "host.h"
#include "misc.h"
#include "machine.h"
struct miss_pile{
md_addr_t tag;
unsigned int isCon;
char block_type;
char culprit_type;
struct miss_pile * next;
}*head=0, *linkPtr, *tail=NULL, *newLink;
typedef struct miss_pile mp;
void add_beg(md_addr_t new_tag/*int new_tag*/, char blk_type, char evicter_type){
newLink = (mp *)malloc(sizeof(mp));
newLink->tag = new_tag;
newLink->block_type = blk_type;
newLink->culprit_type = evicter_type;
newLink->isCon = 0;
if (head == NULL){
head=newLink;
head->next=NULL;
head->tag = new_tag;
head->block_type = blk_type;
head->culprit_type = evicter_type;
head->isCon=0;
}
else if (head != NULL)
{
newLink->next=head;
head = newLink;
}
}
I've determined that this line is where the program seems to stop
head=newLink;
Once I exclude this code, the program runs fine, but of course its pretty essential code. Any help or insight would be greatly appreciated!
A few things to note, the processor stays at 100% while the program "sits". Also, the program I'm adding the list to is SimpleScalar's "sim-cache" simulator.
First, I think you can simplify your function like this :
void add_beg(md_addr_t new_tag/*int new_tag*/, char blk_type, char evicter_type){
newLink = (mp *)malloc(sizeof(mp));
newLink->tag = new_tag;
newLink->block_type = blk_type;
newLink->culprit_type = evicter_type;
newLink->isCon = 0;
/* on the first call, head is NULL, and it's exactly what we want */
newLink->next = head;
/* then head point to the new element */
head = newLink;
}
Secondly, I'm pretty sure that your bug is coming from somewhere else in your code, may be some other functions that interact with your global variable head ? Or it might be anything else of course :)

Resources