How to see if a struct in struct pointer contains an element - c

I have a struct defined as:
typedef struct ltsaNode {
int call;
int action;
ltsaNode *nextActions;
ltsaNode *sibling;
} ltsaNode;
And a struct pointer *wanted and an int i
I want to check if any of the structs in wanted has call equal to i.
My current solution:
BOOL a = FALSE;
for(;wanted!= NULL;wanted->sibling)
{
if(wanted->call == i)
{
a=TRUE;
break;
}
}
Is there a better or faster way to do this ?

This is what you are looking for I guess.
BOOL a = FALSE;
for(; wanted != NULL; wanted = wanted->sibling)
{
if(wanted->call == i)
{
a = TRUE;
break;
}
}

Related

C memcpy() wont copy because size_t is uninitialized

#include <stdlib.h>
typedef struct stackObject
{
void* obj;
struct stackObject *next;
} StackObject_t;
typedef struct stackMeta
{
StackObject_t *stack;
size_t objsize;
int numelem;
} StackMeta_t;
//CREATE
StackMeta_t *mystack_create(size_t objsize)
{
StackMeta_t *elem;
elem = (StackMeta_t*)malloc(sizeof(StackMeta_t));
if(elem == NULL)
{
return NULL;
}
else
{
elem->stack = NULL; // my actual stack basically the first elem(the top)
elem->objsize = objsize; // size of the datatype
elem->numelem = 0; // total count of elem inside the stack
}
return elem;
}
//PUSH
int mystack_push(StackMeta_t *data_stack, void* obj)
{
if(data_stack == NULL)
{
return -1;
}
StackObject_t *nodeObject = NULL;
nodeObject = (StackObject_t*)malloc(sizeof(StackObject_t));
if(nodeObject == NULL)
{
return -1;
}
if(data_stack->stack == NULL)
{
nodeObject->next = NULL;
memcpy(nodeObject->obj, obj, data_stack->objsize);
data_stack->stack = nodeObject;
data_stack->numelem++;
}
else
{
nodeObject->next = data_stack->stack;
memcpy(nodeObject->obj, obj, data_stack->objsize);
data_stack->stack = nodeObject;
data_stack->numelem++;
}
return 0;
}
int main() {
StackMeta_t *METADATA = NULL;
int obj = 1;
METADATA = mystack_create(sizeof(int));
mystack_push(METADATA, &obj);
return 0;
}
This code is Stack with Linked List inside.
So I am trying to copy int obj value to void* obj. from my understanding objcan be any data type so i chose it to be an int type. I am using a visual online tool to see my heap memory and I saw that the value of the 3rd parameter is size_t objsize = 4.
I cannot pin point where my problem is and I have not tested if this has memory leaks.
can someone explain this to me with an example on how to copy void pointers?

I get a segmentation fault because of free even though i used malloc

i am writing a Generic ADT using C and i keep getting a segmentation fault when i free an element
PairResult pairClear(Pair pair)
{
if(pair == NULL)
{
return PAIR_NULL_ARGUMENT;
}
KeyElement key=pair->key;
DataElement data=pair->data;
if(key)
pair->free_key(key);//i get the Error here
if(data)
pair->free_data(data);
return PAIR_SUCCESS;
}
the memory for key and data is allocated :
Pair pairCreate( KeyElement key, DataElement data,
copyDataElements copy_data,
freeDataElements free_data,
copyKeyElements copy_key,
freeKeyElements free_key)
{
Pair pair = malloc(sizeof(*pair));
if(pair == NULL)
{
return NULL;
}
pair->copy_data=copy_data;
pair->copy_key=copy_key;
pair->free_data=free_data;
pair->free_data=free_key;
KeyElement new_string_key = copy_key(key);
DataElement new_string_data = copy_data(data);
if((new_string_key == NULL) || (new_string_data == NULL))
{
pairDestroy(pair);
return NULL;
}
pair->key = new_string_key;
pair->data = new_string_data;
return pair;
}
this pairDestroy
void pairDestroy(Pair pair)
{
if(pair == NULL)
{
return;
}
#ifndef NDEBUG
PairResult result =
#endif
pairClear(pair);
assert(result == PAIR_SUCCESS);
free(pair);
}
these are the copy functions used:
static KeyElement copyKeyInt(KeyElement n) {
if (!n) {
return NULL;
}
int *copy = malloc(sizeof(*copy));
if (!copy) {
return NULL;
}
*copy = *(int *) n;
return copy;
}
static DataElement copyDataChar(DataElement n) {
if (!n) {
return NULL;
}
char *copy = malloc(sizeof(*copy));
if (!copy) {
return NULL;
}
*copy = *(char *) n;
return (DataElement) copy;
}
and these are the free functions used
static void freeInt(KeyElement n) {
free(n);
}
static void freeChar(DataElement n) {
free(n);
}
and here is the struct of pair
struct Pair_t {
KeyElement key;
DataElement data;
copyDataElements copy_data;
freeDataElements free_data;
copyKeyElements copy_key;
freeKeyElements free_key;
};
these are all the typedef used :
typedef struct Pair_t* Pair;
typedef enum PairResult_t {
PAIR_SUCCESS,
PAIR_OUT_OF_MEMORY,
PAIR_NULL_ARGUMENT,
} PairResult;
typedef void *DataElement;
typedef void *KeyElement;
typedef DataElement(*copyDataElements)(DataElement);
typedef KeyElement(*copyKeyElements)(KeyElement);
typedef void(*freeDataElements)(DataElement);
typedef void(*freeKeyElements)(KeyElement);
and a main function so that u could reproduce it
int main()
{
Pair pair;
for (int i = 1; i < 1000; ++i) {
char j = (char) i;
++j;
pair=pairCreate(&i,&j,copyDataChar,freeChar,copyKeyInt,freeInt);
pairDestroy(pair);
}
I added everything I could for a reproducible code
if anything should be edited please tell me in the comments
Pair pairCreate(...) {
...
pair->free_data = free_data;
pair->free_data = free_key;
// ^^^^^^^^^ UH OH
...
You owe me 15 mins of debugging time.

Troubles with linked list - why aren't new elements being added to my list?

My linked list print function keeps printing only one value and I can't figure out why. Everything works as expected.
Here is the struct that I store in linked list:
typedef struct list_element {
int value;
struct list_element *next;
} list_element;
These are the functions to operate on list:
list_element createNewLinkedList()
{
list_element *myElement = (list_element *) malloc(sizeof(list_element));
myElement->value = 0;
myElement->next = NULL;
return *myElement;
}
int insertNewElementAtEndWithValue(list_element element, int value)
{
list_element *myElement = &element;
do {
if (myElement->next == NULL) {
list_element *new = (list_element *)malloc(sizeof(list_element));
new->value = value;
new->next = NULL;
myElement->next = new;
} else {
myElement = myElement->next;
}
} while (myElement->next != NULL);
}
int printListValues(list_element firstNode)
{
list_element *temp = &firstNode;
int sentinel = 1;
while (sentinel) {
printf(" %d,", temp->value);
if (temp->next != NULL) {
temp = temp->next;
} else {
sentinel = 0;
}
}
return 0;
}
And here is the function that prints only first value, 100:
void checkLinkedList()
{
list_element list = createNewLinkedList();
list.value = 100;
for (int i = 1; i < 10; i++) {
int value = rand();
insertNewElementAtEndWithValue(list, value);
}
printListValues(list);
}
What's wrong with that?
Your function
int insertNewElementAtEndWithValue(list_element element, int value)
is accepting a list_element object, meaning, a copy of the head of your list, what you want to pass is a pointer, so:
int insertNewElementAtEndWithValue(list_element *element, int value)
and this way you add the value to the actual list and not a copy of it.
You need to learn to use pointers, and use a debugger to check where your data stays.

how to access first element of a struct array

So I implemented the following method. The problem is that when I begin
searching the variableVector pointer I noticed that variableVector->variables
might not be pointing to the beginning variable element.
Variable* findVariable(VariableVector *variableVector,
char *variableNameOfVariableToReturn) {
if (variableVector->size < 1) {
return NULL ; // since variableVector is empty
}
Variable *currentVariable = variableVector->variables;//<== HOW TO RESET TO BEGINNING???
int numberOfVariablesInVariableVector = variableVector->size;
for (int i = 0; i < numberOfVariablesInVariableVector; i++) {
if (strcmp(currentVariable->variableName,
variableNameOfVariableToReturn) == 0) {
return currentVariable;
} else {
currentVariable++;
}
}
return NULL ; // variable not found in variableVector
}
These are what my structs look like:
struct _Variable {
char *variableName;
char *arrayOfElements;
int32_t address;
};
typedef struct _Variable Variable;
struct _VariableVector {
int size; // elements full in array
int capacity; // total available elements
Variable *variables;
};
typedef struct _VariableVector VariableVector;
Also this is how I add a new variable:
bool appendVariable(VariableVector *variableVector, Variable *variable) {
if (variableVector->size == variableVector->capacity) {
return false;
} else { // append since vector is not full
int indexOfFirstEmptyElement = variableVector->size;
memcpy(&variableVector->variables[indexOfFirstEmptyElement], variable, sizeof(Variable));
//variableVector->variables[indexOfFirstEmptyElement] = *variable;
variableVector->size++;
return true;
}
}

How to implement a stack containing function call for a PIC in C

I'm currently programming a PIC in C with MPLAB X (+ compiler XC8)
In my code, I have some interruptions (inter1, inter2, ..) which are each composed of urgent and non-urgent operations (urg1, urg2, .., n_urg1, n_urg2, ..).
So I'd like a code with the following structure :
stack s; // FIFO or other
main() {
while (true) {
if (!isEmpty(s)) {
doNextFunction(s);
}
}
}
void interrupt inter1() {
urg1(); // urgent code
addStack(n_urg1);
}
void n_urg1() {
// non-urgent code
}
How can I implement that kind of stack ? Is there something in the standard library ?
If I remember correct, then that compiler is rather primitive, I don't think you can use the std library.
If you need to implement it all by yourself, you can use an array of function pointers:
#include <string.h> // for memmove()
#define STACK_MAX 10
typedef enum
{
Int,
Boolean
} VariantType;
typedef struct
{
VariantType type;
union {
int intValue;
bool booleanValue;
} value;
} Variant;
typedef bool (*FunctionPtr)(Variant data);
typedef struct
{
FunctionPtr ptr;
Variant var;
} FunctionCall;
FunctionCall functionStack[STACK_MAX];
int functionStackUse = 0;
bool addStack(FunctionPtr ptr, Variant var)
{
if (functionStackUse >= STACK_MAX)
return false; // stack full
functionStack[functionStackUse].ptr = ptr;
functionStack[functionStackUse].var = var;
functionStackUse++;
return true;
}
bool callNextFunction(void)
{
// TODO: disable inter1
if (functionStackUse > 0)
{
// get first function on stack
FunctionCall functionCall = functionStack[0];
functionStackUse--;
// remove first function from stack
memmove((void*)functionStack, (void*)(functionStack + 1), functionStackUse * sizeof(functionStack[0]));
// TODO: re-enable inter1
// call function with arguments
return (*functionCall.ptr)(functionCall.var);
}
else
{
// TODO: re-enable inter1
return false; // no more functions
}
}
void main()
{
while (1)
{
callNextFunction();
// TODO add some delay otherwise you're constantly disabling inter1 (in doNextFunction)
}
}
bool n_urg1(Variant var)
{
if (var.type == Int)
{
int i = var.value.intValue;
// do something
return true;
}
return false;
}
void inter1(void)
{
Variant var;
var.type = Int;
var.value.intValue = 45;
addStack(n_urg1, var);
}

Resources