ocaml c interop passing struct - c

I hit weird case when trying to call c from ocaml.
This is the c side of things:
typedef struct {
TSNode node;
} AstNode;
CAMLprim value caml_ts_document_root_node(value document) {
CAMLparam1(document);
TSNode root_node = ts_document_root_node(document);
AstNode elNode;
elNode.node = root_node;
CAMLreturn(&elNode);
}
CAMLprim value caml_ts_node_string(value node) {
CAMLparam1(node)
CAMLlocal1(mls);
AstNode* n = (AstNode*) node;
char *s = ts_node_string(n->node);
mls = caml_copy_string(s);
CAMLreturn(mls);
}
On the ocaml side
type ts_point
type ts_document
external ts_node_string : ts_node -> string = "caml_ts_node_string"
external ts_document_root_node : ts_document -> ts_node = "caml_ts_document_root_node"
If you see the code, I'm wrapping in caml_ts_document_root_node the TSNode root_node = ts_document_root_node(document); in an extra defined struct AstNode.
When I write the following implementation however:
CAMLprim value caml_ts_document_root_node(value document) {
CAMLparam1(document);
TSNode root_node = ts_document_root_node(document);
CAMLreturn(&root_node);
}
My code segfaults when calling caml_ts_node_string on the returned node by caml_ts_document_root_node.
Does anyone have any hints on why the segfault appears when I don't wrap a TSNode in an extra struct when interoping from ocaml?

That's definitely not the right usage of the foreign interface! You can't just take a value and cast it to OCaml value. OCaml values are specially encoded, even integers, and have a different representation than C values.
If you want to encode a C value as an OCaml value, you shall use custom values.
First of all, you need to implement the interface of a custom value, fortunately, you can rely on defaults for that:
static struct custom_operations ast_ops = {
"ast_node",
custom_finalize_default
custom_compare_default,
custom_hash_default,
custom_serialize_default,
custom_deserialize_default,
custom_compare_ext_default
};
Next, you need to learn how to allocate custom blocks. For example, the following call will allocate the new AstNode in the OCaml heap:
res = caml_alloc_custom(&ast_ops, sizeof(AstNode), 0, 1);
To access the value itself, you need to use the Data_custom_val macro, e.g.,
if (res) {
AstNode *node = Data_custom_val(res);
TsNode *tsnode = res->node;
}
The complete example of a correct (I hope) implementation of your first function is below:
CAMLprim value caml_ts_document_root_node(value document) {
CAMLparam1(document);
CAMLlocal1(res);
res = caml_alloc_custom(&ast_ops, sizeof(AstNodes), 0, 1);
if (res) {
AstNode *ast = (AstNode *)Data_custom_val(res);
ast->node = ts_document_root_node(document);
}
CAMLreturn(res);
}
As you may see, this is not trivial and rather low-level. Though nothing really magical, especially after you've read the corresponding parts of the OCaml documentation. However, it is much easier to use the CTypes library, that hides most of those complexities and allows you to call C function directly from OCaml

This seems to be unrelated to the ocaml interop part; you are returning the address of a local variable in this function:
CAMLprim value caml_ts_document_root_node(value document) {
// ...
AstNode elNode;
// ...
CAMLreturn(&elNode);
}
When it returns, the (stack) memory it refers to is invalid (in the sense that it will be reused at the next function call).

Related

Pointer assignment truncates the pointer from 64bit to 32bit

I have been trying to modify a piece of code in likewise-open and am totally stumped here.
Some background
Working on this file, trying to code around some LDAP queries:
typedef void *MYH;
typedef MYH HANDLE;
HANDLE hDirectory = NULL;
hDirectory = LsaDmpGetLdapHandle(pConn);
The LsaDmpGetLdapHandle() is defined here
typedef void *MYH;
typedef MYH HANDLE;
HANDLE
LsaDmpGetLdapHandle(
IN PLSA_DM_LDAP_CONNECTION pConn
)
{
return pConn->hLdapConnection;
}
where PLSA_DM_LDAP_CONNECTION is typedef for following struct:
struct _LSA_DM_LDAP_CONNECTION
{
...
// NULL if not connected
HANDLE hLdapConnection;
...
};
Basically, there is HANDLE type everywhere.
Note: Just to avoid various *.h files defining it differently, I added that typedef void *MYH; in both files
The trouble:
The code would crash after the line where hDirectory is assigned from what is returned by LsaDmpGetLdapHandle and I try to further use hDirectory
What I have debugged, till now:
Attaching gdb, hLdapConnection in pConn is:
(gdb) p pConn->hLdapConnection
$5 = (void *) 0x7feb939d6390
However, hDirectory is:
(gdb) p hDirectory
$6 = (void *) 0xffffffff939d6390
I fail to understand why the difference, after assignment ??
Also, to note, the 939d6390 in both the pointer addresses is common.
Interestingly, both of these approaches work
// If I pass hDirectory reference
LsaDmLdapGetHandle(pConn, &hDirectory);
// where this function is defined as, in the other file:
DWORD
LsaDmLdapGetHandle(
IN PLSA_DM_LDAP_CONNECTION pConn,
OUT HANDLE* phDirectory)
{
HANDLE hDirectory = NULL;
hDirectory = LsaDmpGetLdapHandle(pConn);
*phDirectory = hDirectory;
return ERROR_SUCCESS;
}
// Or I call another function, which then call LsaDmpGetLdapHandle(), in the other file
hDirectory = LsaDmLdapGetHandleCopy(pConn);
HANDLE
LsaDmLdapGetHandleCopy(
IN PLSA_DM_LDAP_CONNECTION pConn)
{
HANDLE hDirectory = NULL;
hDirectory = LsaDmpGetLdapHandle(pConn);
return hDirectory;
}
I thought, maybe something to do with HANDLE definitions being different in those 2 files, hence I added my own void * definitions in both files
Looks like dup of this
By default all return values are int. So if a prototype is missing for function then compiler treats the return value as 32-bit and generates code for 32-bit return value. Thats when your upper 4 bytes gets truncated.

Parallelisation in R: Using parLapply with pointer to C object

I'm trying to parallelise an R function that conducts some arithmetic in C.
A C object is constructed once from an R dataset using some function, which I'll call InitializeCObject, that returns a pointer to the object. I want to create an instance of this object on each worker that I can reuse many times.
This is where I've got so far:
nCores <- 2
cluster <- makeCluster(nCores)
on.exit(stopCluster(cluster))
clusterEvalQ(cluster, {library(pkgName); NULL})
The simplest solution is to make a new C object on each call:
x <- list(val1, val2) # list of length `nCores`
parLapply(cluster, x, function (x_i) pkgName::MakeObjectAndCalc(x_i, dataset))
But the time spent initializing the C object on every single call outweighs the benefits of parallelization.
I've tried creating nCores C objects and exporting all of them to each worker, then making worker n use local object n:
cPointer <- lapply(seq_len(nCores), function(xx) InitializeCObject(dataset))
on.exit(DestroyCObject(cPointer), add=TRUE)
clusterExport(cluster, 'cPointer')
parLapply(cluster, seq_len(nCores), function (i) Calculate(x[[i]], cPointer[[i]]))
But this doesn't work; the objects on the workers seem not to be initialized.
So I tried creating a separate C object locally on each worker:
clusterExport(cluster, 'dataset')
clusterEvalQ(cluster, {
localPointer <- InitializeCObject(dataset)
LocalCalc <- function (x) Calculate(x, localPointer)
on.exit(DestroyCObject(localPointer))
}
parLapply(cluster, x, LocalCalc)
But this causes the workers to crash. Any suggestions as to how I might move forwards would be appreciated.
edit: minimal C example
Here's my attempt to provide a minimal example of the associated C code. I'm far from fluent in C structures but hopefully this code is sufficient to demonstrate my problem.
// Define object structure
typedef struct CObject_t {
int data;
} CObject_t *CObject;
// Allocate memory to new (empty) object and return pointer to it
CObject new_object_t(void) {
CObject new = (CObject)calloc(1, sizeof(CObject_t));
return new;
}
int initialize_object(const int *dataset, CObject cObj) {
cObj->data = *dataset;
}
int use_object_to_calculate(int *x, CObject cObj) {
*x = *x + cObj->data;
return x;
}

Store extra data in a c function pointer

Suppose there is a library function (can not modify) that accept a callback (function pointer) as its argument which will be called at some point in the future. My question: is there a way to store extra data along with the function pointer, so that when the callback is called, the extra data can be retrieved. The program is in c.
For example:
// callback's type, no argument
typedef void (*callback_t)();
// the library function
void regist_callback(callback_t cb);
// store data with the function pointer
callback_t store_data(callback_t cb, int data);
// retrieve data within the callback
int retrieve_data();
void my_callback() {
int a;
a = retrieve_data();
// do something with a ...
}
int my_func(...) {
// some variables that i want to pass to my_callback
int a;
// ... regist_callback may be called multiple times
regist_callback(store_data(my_callback, a));
// ...
}
The problem is because callback_t accept no argument. My idea is to generate a small piece of asm code each time to fill into regist_callback, when it is called, it can find the real callback and its data and store it on the stack (or some unused register), then jump to the real callback, and inside the callback, the data can be found.
pseudocode:
typedef struct {
// some asm code knows the following is the real callback
char trampoline_code[X];
callback_t real_callback;
int data;
} func_ptr_t;
callback_t store_data(callback_t cb, int data) {
// ... malloc a func_ptr_t
func_ptr_t * fpt = malloc(...);
// fill the trampoline_code, different machine and
// different calling conversion are different
// ...
fpt->real_callback = cb;
fpt->data = data;
return (callback_t)fpt;
}
int retrieve_data() {
// ... some asm code to retrive data on stack (or some register)
// and return
}
Is it reasonable? Is there any previous work done for such problem?
Unfortunately you're likely to be prohibited from executing your trampoline in more and more systems as time goes on, as executing data is a pretty common way of exploiting security vulnerabilities.
I'd start by reporting the bug to the author of the library. Everybody should know better than to offer a callback interface with no private data parameter.
Having such a limitation would make me think twice about how whether or not the library is reentrant. I would suggest ensuring you can only have one call outstanding at a time, and store the callback parameter in a global variable.
If you believe that the library is fit for use, then you could extend this by writing n different callback trampolines, each referring to their own global data, and wrap that up in some management API.

Opaque C structs: various ways to declare them

I've seen both of the following two styles of declaring opaque types in C APIs. What are the various ways to declare opaque structs/pointers in C? Is there any clear advantage to using one style over the other?
Option 1
// foo.h
typedef struct foo * fooRef;
void doStuff(fooRef f);
// foo.c
struct foo {
int x;
int y;
};
Option 2
// foo.h
typedef struct _foo foo;
void doStuff(foo *f);
// foo.c
struct _foo {
int x;
int y;
};
My vote is for the third option that mouviciel posted then deleted:
I have seen a third way:
// foo.h
struct foo;
void doStuff(struct foo *f);
// foo.c
struct foo {
int x;
int y;
};
If you really can't stand typing the struct keyword, typedef struct foo foo; (note: get rid of the useless and problematic underscore) is acceptable. But whatever you do, never use typedef to define names for pointer types. It hides the extremely important piece of information that variables of this type reference an object which could be modified whenever you pass them to functions, and it makes dealing with differently-qualified (for instance, const-qualified) versions of the pointer a major pain.
Option 1.5 ("Object-based" C Architecture):
I am accustomed to using Option 1, except where you name your reference with _h to signify it is a "handle" to a C-style "object" of this given C "class". Then, you ensure your function prototypes use const wherever the content of this object "handle" is an input only, and cannot be changed, and don't use const wherever the content can be changed. So, do this style:
// -------------
// my_module.h
// -------------
// An opaque pointer (handle) to a C-style "object" of "class" type
// "my_module" (struct my_module_s *, or my_module_h):
typedef struct my_module_s *my_module_h;
void doStuff1(my_module_h my_module);
void doStuff2(const my_module_h my_module);
// -------------
// my_module.c
// -------------
// Definition of the opaque struct "object" of C-style "class" "my_module".
struct my_module_s
{
int int1;
int int2;
float f1;
// etc. etc--add more "private" member variables as you see fit
};
Here's a full example using opaque pointers in C to create objects. The following architecture might be called "object-based C":
//==============================================================================================
// my_module.h
//==============================================================================================
// An opaque pointer (handle) to a C-style "object" of "class" type "my_module" (struct
// my_module_s *, or my_module_h):
typedef struct my_module_s *my_module_h;
// Create a new "object" of "class" "my_module": A function that takes a *pointer to* an
// "object" handle, `malloc`s memory for a new copy of the opaque `struct my_module_s`, then
// points the user's input handle (via its passed-in pointer) to this newly-created "object" of
// "class" "my_module".
void my_module_open(my_module_h * my_module_h_p);
// A function that takes this "object" (via its handle) as an input only and cannot modify it
void my_module_do_stuff1(const my_module_h my_module);
// A function that can modify the private content of this "object" (via its handle) (but still
// cannot modify the handle itself)
void my_module_do_stuff2(my_module_h my_module);
// Destroy the passed-in "object" of "class" type "my_module": A function that can close this
// object by stopping all operations, as required, and `free`ing its memory.
void my_module_close(my_module_h my_module);
//==============================================================================================
// my_module.c
//==============================================================================================
// Definition of the opaque struct "object" of C-style "class" "my_module".
// - NB: Since this is an opaque struct (declared in the header but not defined until the source
// file), it has the following 2 important properties:
// 1) It permits data hiding, wherein you end up with the equivalent of a C++ "class" with only
// *private* member variables.
// 2) Objects of this "class" can only be dynamically allocated. No static allocation is
// possible since any module including the header file does not know the contents of *nor the
// size of* (this is the critical part) this "class" (ie: C struct).
struct my_module_s
{
int my_private_int1;
int my_private_int2;
float my_private_float;
// etc. etc--add more "private" member variables as you see fit
};
void my_module_open(my_module_h * my_module_h_p)
{
// Ensure the passed-in pointer is not NULL (since it is a core dump/segmentation fault to
// try to dereference a NULL pointer)
if (!my_module_h_p)
{
// Print some error or store some error code here, and return it at the end of the
// function instead of returning void.
goto done;
}
// Now allocate the actual memory for a new my_module C object from the heap, thereby
// dynamically creating this C-style "object".
my_module_h my_module; // Create a local object handle (pointer to a struct)
// Dynamically allocate memory for the full contents of the struct "object"
my_module = malloc(sizeof(*my_module));
if (!my_module)
{
// Malloc failed due to out-of-memory. Print some error or store some error code here,
// and return it at the end of the function instead of returning void.
goto done;
}
// Initialize all memory to zero (OR just use `calloc()` instead of `malloc()` above!)
memset(my_module, 0, sizeof(*my_module));
// Now pass out this object to the user, and exit.
*my_module_h_p = my_module;
done:
}
void my_module_do_stuff1(const my_module_h my_module)
{
// Ensure my_module is not a NULL pointer.
if (!my_module)
{
goto done;
}
// Do stuff where you use my_module private "member" variables.
// Ex: use `my_module->my_private_int1` here, or `my_module->my_private_float`, etc.
done:
}
void my_module_do_stuff2(my_module_h my_module)
{
// Ensure my_module is not a NULL pointer.
if (!my_module)
{
goto done;
}
// Do stuff where you use AND UPDATE my_module private "member" variables.
// Ex:
my_module->my_private_int1 = 7;
my_module->my_private_float = 3.14159;
// Etc.
done:
}
void my_module_close(my_module_h my_module)
{
// Ensure my_module is not a NULL pointer.
if (!my_module)
{
goto done;
}
free(my_module);
done:
}
Simplified example usage:
#include "my_module.h"
#include <stdbool.h>
#include <stdio.h>
int main()
{
printf("Hello World\n");
bool exit_now = false;
// setup/initialization
my_module_h my_module = NULL;
// For safety-critical and real-time embedded systems, it is **critical** that you ONLY call
// the `_open()` functions during **initialization**, but NOT during normal run-time,
// so that once the system is initialized and up-and-running, you can safely know that
// no more dynamic-memory allocation, which is non-deterministic and can lead to crashes,
// will occur.
my_module_open(&my_module);
// Ensure initialization was successful and `my_module` is no longer NULL.
if (!my_module)
{
// await connection of debugger, or automatic system power reset by watchdog
log_errors_and_enter_infinite_loop();
}
// run the program in this infinite main loop
while (exit_now == false)
{
my_module_do_stuff1(my_module);
my_module_do_stuff2(my_module);
}
// program clean-up; will only be reached in this case in the event of a major system
// problem, which triggers the infinite main loop above to `break` or exit via the
// `exit_now` variable
my_module_close(my_module);
// for microcontrollers or other low-level embedded systems, we can never return,
// so enter infinite loop instead
while (true) {}; // await reset by watchdog
return 0;
}
The only improvements beyond this would be to:
Implement full error handling and return the error instead of void. Ex:
/// #brief my_module error codes
typedef enum my_module_error_e
{
/// No error
MY_MODULE_ERROR_OK = 0,
/// Invalid Arguments (ex: NULL pointer passed in where a valid pointer is required)
MY_MODULE_ERROR_INVARG,
/// Out of memory
MY_MODULE_ERROR_NOMEM,
/// etc. etc.
MY_MODULE_ERROR_PROBLEM1,
} my_module_error_t;
Now, instead of returning a void type in all of the functions above and below, return a my_module_error_t error type instead!
Add a configuration struct called my_module_config_t to the .h file, and pass it in to the open function to update internal variables when you create a new object. This helps encapsulate all configuration variables in a single struct for cleanliness when calling _open().
Example:
//--------------------
// my_module.h
//--------------------
// my_module configuration struct
typedef struct my_module_config_s
{
int my_config_param_int;
float my_config_param_float;
} my_module_config_t;
my_module_error_t my_module_open(my_module_h * my_module_h_p,
const my_module_config_t *config);
//--------------------
// my_module.c
//--------------------
my_module_error_t my_module_open(my_module_h * my_module_h_p,
const my_module_config_t *config)
{
my_module_error_t err = MY_MODULE_ERROR_OK;
// Ensure the passed-in pointer is not NULL (since it is a core dump/segmentation fault
// to try to dereference a NULL pointer)
if (!my_module_h_p)
{
// Print some error or store some error code here, and return it at the end of the
// function instead of returning void. Ex:
err = MY_MODULE_ERROR_INVARG;
goto done;
}
// Now allocate the actual memory for a new my_module C object from the heap, thereby
// dynamically creating this C-style "object".
my_module_h my_module; // Create a local object handle (pointer to a struct)
// Dynamically allocate memory for the full contents of the struct "object"
my_module = malloc(sizeof(*my_module));
if (!my_module)
{
// Malloc failed due to out-of-memory. Print some error or store some error code
// here, and return it at the end of the function instead of returning void. Ex:
err = MY_MODULE_ERROR_NOMEM;
goto done;
}
// Initialize all memory to zero (OR just use `calloc()` instead of `malloc()` above!)
memset(my_module, 0, sizeof(*my_module));
// Now initialize the object with values per the config struct passed in. Set these
// private variables inside `my_module` to whatever they need to be. You get the idea...
my_module->my_private_int1 = config->my_config_param_int;
my_module->my_private_int2 = config->my_config_param_int*3/2;
my_module->my_private_float = config->my_config_param_float;
// etc etc
// Now pass out this object handle to the user, and exit.
*my_module_h_p = my_module;
done:
return err;
}
And usage:
my_module_error_t err = MY_MODULE_ERROR_OK;
my_module_h my_module = NULL;
my_module_config_t my_module_config =
{
.my_config_param_int = 7,
.my_config_param_float = 13.1278,
};
err = my_module_open(&my_module, &my_module_config);
if (err != MY_MODULE_ERROR_OK)
{
switch (err)
{
case MY_MODULE_ERROR_INVARG:
printf("MY_MODULE_ERROR_INVARG\n");
break;
case MY_MODULE_ERROR_NOMEM:
printf("MY_MODULE_ERROR_NOMEM\n");
break;
case MY_MODULE_ERROR_PROBLEM1:
printf("MY_MODULE_ERROR_PROBLEM1\n");
break;
case MY_MODULE_ERROR_OK:
// not reachable, but included so that when you compile with
// `-Wall -Wextra -Werror`, the compiler will fail to build if you forget to handle
// any of the error codes in this switch statement.
break;
}
// Do whatever else you need to in the event of an error, here. Ex:
// await connection of debugger, or automatic system power reset by watchdog
while (true) {};
}
// ...continue other module initialization, and enter main loop
See also:
[another answer of mine which references my answer above] Architectural considerations and approaches to opaque structs and data hiding in C
Additional reading on object-based C architecture:
Providing helper functions when rolling out own structures
Additional reading and justification for valid usage of goto in error handling for professional code:
An argument in favor of the use of goto in C for error handling: https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/blob/master/Research_General/goto_for_error_handling_in_C/readme.md
*****EXCELLENT ARTICLE showing the virtues of using goto in error handling in C: "Using goto for error handling in C" - https://eli.thegreenplace.net/2009/04/27/using-goto-for-error-handling-in-c
Valid use of goto for error management in C?
Error handling in C code
Search terms to make more googlable: opaque pointer in C, opaque struct in C, typedef enum in C, error handling in C, c architecture, object-based c architecture, dynamic memory allocation at initialization architecture in c
bar(const fooRef) declares an immutable address as argument. bar(const foo *) declares an address of an immutable foo as argument.
For this reason, I tend to prefer option 2. I.e., the presented interface type is one where cv-ness can be specified at each level of indirection. Of course one can sidestep the option 1 library writer and just use foo, opening yourself to all sorts of horror when the library writer changes the implementation. (I.e., the option 1 library writer only perceives that fooRef is part of the invariant interface and that foo can come, go, be altered, whatever. The option 2 library writer perceives that foo is part of the invariant interface.)
I'm more surprised that no one's suggested combined typedef/struct constructions.
typedef struct { ... } foo;
Option 3: Give people choice
/* foo.h */
typedef struct PersonInstance PersonInstance;
typedef struct PersonInstance * PersonHandle;
typedef const struct PersonInstance * ConstPersonHandle;
void saveStuff (PersonHandle person);
int readStuff (ConstPersonHandle person);
...
/* foo.c */
struct PersonInstance {
int a;
int b;
...
};
...

Variable Persistence in Linked List

I'm making a domino game and when the user adds a domino to the left, the domino is added but when the function exits the domino added is GONE.
FYI:
fitxesJoc (Link List) contains the dominoes of
the game and is a pointer passed to the function (so that it lasts all the game)
opcionesCorrectas (Domino) contains the correct choices of domino
inferior (int) contains the smaller number of the domino
superior (int) contains the bigger number of the domino
pos (int) the position of the domino
opcionFitxa (int) contains the choice of the player
ultimaFitxa->seg is the 'next' node
tNode* ultimaFitxa = (tNode *)malloc(sizeof(tNode));
ultimaFitxa->info.inferior = opcionesCorrectas[opcionFitxa - 1].inferior;
ultimaFitxa->info.superior = opcionesCorrectas[opcionFitxa - 1].superior;
ultimaFitxa->info.pos = opcionesCorrectas[opcionFitxa - 1].pos;
ultimaFitxa->seg = fitxesJoc;
fitxesJoc = ultimaFitxa;
Header of the function
unsigned int demanar_fitxa_tirar(tJugador *jugador, tNode* fitxesJoc, tPartida *partida, tPila* fitxesBarrejades, bool primerCop)
Call of the function
resultado = demanar_fitxa_tirar(&Jugadors[jugadorActual], fitxesJoc, partida, fitxesBarrejades, true);
This way I add the domino, in the top of the other dominoes.
Your problem is that the last line of demanar_fitxa_tirar:
fitxesJoc = ultimaFitxa;
is assigning to a local variable, which has no effect on the calling code. You need to pass a pointer to the calling code's fitxesJoc, like this:
unsigned int demanar_fitxa_tirar(..., tNode** fitxesJoc, ...) // Note extra *
{
// ...
*fitxesJoc = ultimaFitxa; // Note extra *
}
void mainProgram()
{
tNode* fitxesJoc;
// ...
resultado = demanar_fitxa_tirar(..., &fitxesJoc, ...); // Note extra &
// ...
}
From your code, it's not clear where your function starts and ends and what it takes as parameters but I guess your problem is with the fitxesJoc variable which is probably passed as an argument to the function. C copies arguments when calling functions (call-by-value). You could pass the address to fitxesJoc variable using a pointer instead and rewrite it as something like this:
// fitxesJoc would be a `tNode**` rather than `tNode*`.
tNode* ultimaFitxa = (tNode *)malloc(sizeof(tNode));
ultimaFitxa->info.inferior = opcionesCorrectas[opcionFitxa - 1].inferior;
ultimaFitxa->info.superior = opcionesCorrectas[opcionFitxa - 1].superior;
ultimaFitxa->info.pos = opcionesCorrectas[opcionFitxa - 1].pos;
ultimaFitxa->seg = *fitxesJoc;
*fitxesJoc = ultimaFitxa;
I don't think you've provided enough code, but I suspect the problem is in:
fitxesJoc = ultimaFitxa;
(Linked-list now equals the new Node).
The problem is that parameters are passed by value.
If you want to change the value of the parameter, you'll need to pass by pointer,
and use the pointer to change the value.
*pfitxesJoc = ultimaFitxa;
Please provide more code, including the function header and the function call, for a better answer.
It looks like you're not actually adding the new domino to the linked list. But, it's hard to tell because you need to post more code, and because your code isn't in English.

Resources