Best way to pass a struct within a struct to a GSourceFunc - c

Which way is best to get S to a GSourceFunc? Or neither?
typedef struct{
//...
}S;
struct MS{
//..
S *St;
};
static gboolean AL_Calback(gpointer data){
S *St = (S*)user_data;
St->Something = SomethingElse;
return TRUE;
}
int main (int argc, char *argv[]){
//...
MS *MainStruct = gnew0(MS, 1);
Mainstruct->St = gnew0(S, 1);
clutter_threads_add_timeout_full(G_PRIORITY_HIGH, 100, AL_Callback, MainStruct->St, NULL);
//...
}
or like this,
typedef struct{
//...
}S;
struct MS{
//..
S St;
};
static gboolean AL_Calback(gpointer data){
MS *MV = (MS*)user_data;
MV->S.something = SomethingElse;
return TRUE;
}
int main (int argc, char *argv[]){
//...
MS *MainStruct = gnew0(MS, 1);
clutter_threads_add_timeout_full(G_PRIORITY_HIGH, 100, AL_Callback, MainStruct, NULL);
//...
}
I've tried other ways, but have not been able to make them work. clutter_add_timeout needs to take a pointer as an argument.

If you are passing the parameter to clutter_threads_add_timeout_Full via pointer, then you could just pass the address of the St member of MainStruct thus reducing the need for dynamic allocation (for the inner structure).
struct MainStruct{
//..
S St; // note: no pointer
};
// in main
MainStruct* ms = gnew0(MS, 1);
clutter_threads_add_timeout_Full(G_PRIORITY_HIGH, 100, AL_Callback, &(ms->St),
NULL);
Edit: updated code to dynamically allocate MainStruct structure to avoid possible segfault as pointed out by ptomato

Related

Dynamic stack assing value to a struct inside the stack struct

I'm having a problem in line: novo->conta.nome_cliente = valor2;. In this dynamic stack structure. Empilhar is a function to push a new element to the stack. Why i cant assign a new value to the structure inside the stack?
struct conta_de_luz
{
int cod_cliente;
char nome_cliente[40];
};
typedef struct Item {
struct conta_de_luz conta;
struct Item *anterior;
} Elemento;
void Inicializar(Elemento **topo) {
*topo = NULL;
}
int EstaVazia(Elemento **topo) {
if(*topo == NULL)
return VERD;
else
return FALSO;
}
void Empilhar(Elemento **topo, int valor, char valor2) {
Elemento *novo;
novo = (Elemento *) malloc(sizeof(Elemento));
novo->conta.cod_cliente = valor;
novo->conta.nome_cliente = valor2;
novo->anterior = *topo;
*topo = novo;
}
The problem is that line novo->conta.nome_cliente = valor2; assigns a char to something that is a string defined as char nome_cliente[40];.
So your function probably should have been void Empilhar(Elemento **topo, int valor, char* valor2). But that would still assume the value of valor2 remains in memory for the lifetime of topo.
Better would be void Empilhar(Elemento **topo, int valor, const char* valor2) and then use strcpy(novo->conta.nome_cliente, valor2);.
But this assumes valor2 including its NULL-terminator always fits within 40 characters. If this assumption is not guaranteed it's better to duplicate the string using strdup(). You will then also need to free() this seperately this in your cleanup function.

Is it possible to only send one variable from a struct if that struct exists as an array?

I apologise if this seems simple, I'm still learning and I'm new to C.
I have this as my struct:
struct Game{
char id;
char name[50];
char genre[20];
char platform[15];
char company[30];
float price;
int quantity = 10;
};
And this declared as a struct array:
struct Game gList[30];
I have a function where I'm passing all of 'gList' to search through values in the gList[i].name variables.
So my question is, is it possible to send only the gList[i].name part of the struct to the function as a parameter?(ie All the 30 name values only).
No.
But you could make an array of pointers that point to the name field and pass it to the function:
char* ptr[30];
for(int i = 0; i < 30; i++)
ptr[i] = gList[i].name;
func(ptr);
No you can't. However, you can pass iterators to functions just fine. Typical pattern:
struct context { struct Game *gList; int nList; int i; }
char *iter_names(void *baton)
{
struct context *ptr = baton;
if (ptr->i == ptr->nList) return NULL;
return ptr->gList[ptr->i++].name;
}
void wants_name_array(char (*nextname)(void *), void *baton)
{
while (char *name = nextname(baton))
{
printf("%s\n", name);
/* and whatever else you are doing */
}
}
/* ... */
struct context baton = { gList, 30, 0 };
wants_name_array(iter_names, baton);
Yeah it looks kinda bad. Thankfully, gcc has an extension that makes this much better.
void wants_name_array(char (*nextname)())
{
while (char *name = nextname())
{
printf("%s\n", name);
/* and whatever else you are doing */
}
}
/* ... */
{
int i = 0;
char *nextname()
{
if (i == 30) return NULL;
return gList[i++].name;
}
wants_name_array(nextname);
}
When using this particular gcc extension, never ever return nested functions. Undefined behavior.

What is best solution for initialize struct array?

First solution:
struct str {
char *name;
int flag;
};
enum {
HELP,
OUTPUT,
OTHER
};
typedef struct str table;
table arr[] = {
{ "help", HELP },
{ "output", OUTPUT },
{ NULL, OTHER },
};
int main(int argc, char **argv) {
table *opt = arr;
printf("%s\n", (opt+HELP)->name);
printf("%s\n", (opt+OUTPUT)->name);
return 0;
}
Second solution:
struct str {
char *name;
int flag;
};
enum {
HELP,
OUTPUT,
OTHER
};
typedef struct str table;
table arr[OTHER];
void start_table() {
arr[HELP] = (struct str) { "help", HELP };
arr[OUTPUT] = (struct str) { "output", OUTPUT };
arr[OTHER] = (struct str) { NULL, OTHER };
}
int main(int argc, char **argv) {
start_table();
table *opt = arr;
printf("%s\n", (opt+HELP)->name);
printf("%s\n", (opt+OUTPUT)->name);
return 0;
}
What are the best? Second solution change automatically if I add or change any element of the array, but is efficient? Is the best enumerate or using the #define preprocessor directive?
It depends!
When initialization can be used, use it — so the first solution is often better, especially if the code never changes the structure (array) contents.
If your code can change the contents but might need to be able to reset to the original state, then the initialization function becomes more appropriate and using direct initialization is not appropriate.
There is no one 'best' solution; what is best depends on what you need to do with the array.
Using a C99 specific intializer syntax, you can get the advantages of the second approach in a static initializer:
#include <stdio.h>
struct str {
const char *name;
int flag;
};
enum {
HELP,
OUTPUT,
OTHER,
};
typedef struct str table;
table arr[] = {
[HELP] = { "help", HELP },
[OUTPUT] = { "output", OUTPUT },
[OTHER] = { NULL, OTHER },
};
int main(int argc, char **argv) {
table *opt = arr;
printf("%s\n", opt[HELP].name);
printf("%s\n", opt[OUTPUT].name);
return 0;
}
The advantage of this technique is it makes no assumption on the order of the enum values, nor on their actual values as long as they are positive, distinct and reasonably small.

How to assign a void** array (return value of a function) to a variable?

Needed: A function which returns two different values (int,str)
So foo calculates smth. and stores the addresses of the two values
in the return array.
Now I want to read the values back into variables of these types.
void** foo(){
void** bar = malloc(2 * sizeof(void*));
...
return bar;
}
int main(int argc, char* argv[]){
void** result = foo();
int* val1 = (int*)result[0];
char* val2 = (char*)result[1];
}
This snippet is not compiling.
Excuse me:
the problem was not the code but that I declared it in a case branch
without any compution instructions.
int main(int argc, char* argv[]){
switch(xyz){
case a:
void** result = foo();
int* val1 = (int*)result[0];
char* val2 = (char*)result[1];
break;
}
}
Which seems not to make sense in a case.
Thanks though.
If you come up with the need to use a void**, it is a strong indication of poor program design. Just forget about this idea. void pointers in general is something you should avoid.
What you actually want to do seems to be something like this:
typedef struct
{
int i;
char c;
} something_t;
something_t* foo (void)
{
something_t* result = malloc (sizeof(*result));
...
return result;
}
int main(int argc, char* argv[]){
something_t* result = foo();
int* val1 = &result->i;
char* val2 = &result->c;
}
If the struct members need to be pointers, simply change the struct.
You should use structure to do your job
#include <stdio.h>
#include <stdlib.h>
#define STRING_WIDTH 32
struct test
{
int val1;
char *val2;
};
struct test *foo(void)
{
struct test *bar = malloc(sizeof(struct test));
if (bar != NULL)
{
bar->val1 = 0;
bar->val2 = calloc (STRING_WIDTH, 1);
if (bar->val2 == NULL)
return NULL;
}
return bar;
}
int main( void )
{
struct test *result = foo();
if (result != NULL)
{
// USE YOUR STRUCT
}
return 0;
}
Take note that mallocated memory must be freed

How to work with pointer to pointer to a struct?

I have a bit of a problem. I am barely starting out with C, (comming from a C# background) and I am having problem with double pointers.
I have a structure as follows:
#ifndef __PROCESSINFO_H
#define __PROCESSINFO_H
struct ProcessInfo
{
int ProcesId;
int Priority;
int ExecutionTime;
int EllapsedTime;
char* ProcessName;
};
struct ProcessInfo *ProcessInfo_Allocate(int processId, char *processName, int priority, int executionTime);
void ProcessInfo_ToString(struct ProcessInfo *processInfo);
void ProcessInfo_Dispose(struct ProcessInfo *processInfo);
#endif
Implementation:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "processinfo.h"
struct ProcessInfo *ProcessInfo_Allocate(int processId, char *processName, int priority, int executionTime)
{
struct ProcessInfo *processInfo;
processInfo = (struct ProcessInfo *)malloc(sizeof(struct ProcessInfo));
processInfo->ProcessId = processId;
processInfo->ProcessName = processName;
processInfo->Priority = priority;
processInfo->ExecutionTime = executionTime;
processInfo->EllapsedTime = 0;
return processInfo;
}
void ProcessInfo_ToString(struct ProcessInfo *processInfo)
{
printf(" %6i %6i %10i %10i, %25s", processInfo->ProcessId, processInfo->Priority, processInfo->ExecutionTime, processInfo->EllapsedTime, processInfo->ProcessName);
}
void ProcessInfo_Dispose(struct ProcessInfo *processInfo)
{
if(processInfo != NULL)
{
if(processInfo->ProcessName != NULL)
{
free(processInfo->ProcessName);
}
free(processInfo);
}
}
so now I have to manage a whole lot of ProcessInfo instances. I wrote another structure which would hold a pointer to a pointer to the ProcessInfo sturcture because i thought that I can increase and decrease it in size as needed (without too much hassle);
#ifndef __SCHEDULER_H
#define __SCHEDULER_H
struct Scheduler
{
struct ProcessInfo** Processes;
};
struct Scheduler* Scheduler_Allocate(void);
#endif
So the question is how do I initialize the **Processes member inside the Scheduler_Allocate method? How do I add stuff to it?
struct Scheduler s;
s.Processes = malloc(sizeof(struct ProcessInfo*) * size);
s.Processes[0] = ProcessInfo_Allocate(...);
// Add more items:
s.Processes = realloc(malloc(sizeof(struct ProcessInfo*) * (size + 1));
s.Processes[size] = ProcessInfo_Allocate(...);
size++;
Also see my example here:
Array of C structs
You don't need a double pointer to increase/decrease the size. Just use a normal pointer and realloc.
struct ProcessInfo* processes = malloc(sizeof(struct ProcessInfo) * 2);
struct ProcessInfo* processes_tmp;
if (!processes) {
/* bail */
}
/* do whatever with processes[0] and [1] */
processes_tmp = processes;
processes = realloc(processes, sizeof(struct ProcessInfo) * 5);
if (!processes) {
free(processes_tmp);
/* bail */
}
/* processes[0] and [1] are unchanged, and [2] [3] and [4] are now valid */
Then instead of having a ProcessInfo_Allocate, you could create a ProcessInfo_Init that would do most of the same except not allocating the memory:
int ProcessInfo_Init(struct ProcessInfo *pi, int processId, char *processName, int priority, int executionTime)
{
if (!pi) {
return -1;
}
pi->ProcessId = processId;
pi->ProcessName = processName;
pi->Priority = priority;
pi->ExecutionTime = executionTime;
pi->EllapsedTime = 0;
return 0;
}
size_t size = 10;//or what ever is the number of processes
struct ProcessInfo * process = (struct ProcessInfo *)malloc(size * sizeof(struct ProcessInfo));
if(!process)
//perhaps stop program? Do something
Processes = &process;
//later on
int i;
for(i = 0; i < size; i++)
{
printf("Process id =%d",Processes[i]->ProcesId);
etc
}
Pointer to pointer is initialized as array of pointers. So call malloc(count * sizeof(ProcessInfo*)) to initialize it. This way you get array of pointers to ProcessInfo. Then call malloc(sizeof(ProcessInfo)) many times to create particular ProcessInfo structures and put pointers to them to the array.
Also, user470379 is right that you don't need pointer to pointer just to change number of items in your array. But your idea is actually not bad either, you can stay with it if you want.
Also, since you are familiar with C#, I would recommend you to start with writing something like ArrayList in C. Then you can use it in many situations (like this one).
First change your definition to:
typedef struct Scheduler {
struct ProcessInfo** Processes;
} Scheduler;
Then something like this:
Scheduler *s;
s = malloc(sizeof(Scheduler));
if (s == NULL) {
exit(-1);
}
s = memset(s, 0, sizeof(Scheduler));
/* Or enter your own memory allocation stuff here */
i = 0; /* Or use some other number */
s->Processes[i] = someProcessInfo;

Resources