C pointer to array in struct passed into function - c

I am trying to pass a pointer to an array, inside a structure into a callback function for an sqlite3 operation. Unfortunately the logic stemming from my understanding of pointers (obviously missing something) does not work.
Simplified, this is what I have:
typedef struct sqlCallbackData
{
int16_t data_array[128][32];
// There are other members here too...
} SqlCallbackData_t;
//===========================================================================================================
//===========================================================================================================
void sql_getData(uint8_t seq_num, uint8_t seq_bank, int16_t *data, char *name)
{
// 'data' above will be a pointer to a 2D array
//...
// Initialise struct members to be passed into callback...
SqlCallbackData_t paramStruct;
//Thows: error: incompatible types when assigning to type 'int16_t[128][32]' from type 'int16_t *'
paramStruct.data_array = data;// I know this isn't right...
//...
// Pointer to paramStruct passed into void pointer in callback...
if (sqlite3_exec(dbPtr, sql, callback, &paramStruct, &zErrMsg) != SQLITE_OK)
{
fprintf (stderr, "SQL error: %s\r\n", zErrMsg);
sqlite3_free(zErrMsg);
}
//...
}
//===========================================================================================================
//===========================================================================================================
// Callback function
static int load_callback(void *paramStruct, int argc, char **argv, char **azColName)
{
int i;
uint8_t value;
//...
// Just making the syntax below a bit mroe readable, as I access members a fair bit in this function
SqlCallbackData_t *params = ((SqlCallbackData_t *)paramStruct);
//...
// Data retreived from sql database...
params->data_array[0][0] = value;// <- What I'm trying to acheive...obviosuly not correct
return 0;
}
So I am aware of how pointers to array are passed into functions (explained here ), but I am getting confused as to how i assign this pointer to array into a structure, to be passed into a function (and then be accessed as an array again).
Going round in circles, so any help would be greatly appreciated:)

I am trying to pass a pointer to an array, inside a structure
for that you need to change struct like this,look at two dimensional array pointer
typedef struct sqlCallbackData
{
int16_t (*data_array)[32]; //2d array pointer
// There are other members here too...
} SqlCallbackData_t;
When you assign address to pointer...
void sql_getData(uint8_t seq_num, uint8_t seq_bank, int16_t (*data)[32], char *name)
{
// 'data' above will be a pointer to a 2D array
// Initialise struct members to be passed into callback...
SqlCallbackData_t paramStruct;
paramStruct.data_array = data;

Assuming the data is always large enough to fill the whole data_array:
memcpy(paramStruct.data_array, data, sizeof(paramStruct.data_array))
Otherwise, take care to copy as much data as you actually have instead of just sizeof(whole array).
Array declared like that is not a pointer, it's a part of the structure.
That structure is at least 8KB long.

Related

Passing a struct to void* param then copying it to a void*, reconstructing gives garbage value

I am really confused with passing my struct to void pointers, I'm not sure which one can be assigned directly and which one should be memcpyed, I've tried a lot of combinations but it does not seem to work. Any help would be very appreciated!
This is my C code
struct SomeStruct {
int a;
char name[10];
};
void *randoms[10];
void transferFunction(void* data, int index) {
// This function copies data to randoms[index]
// I would like to have the whole struct's data in randoms[index]
memcpy(&randoms[index], data, sizeof(struct SomeStruct));
}
struct SomeStruct *ss = malloc(sizeof(struct SomeStruct));
ss->a = 1;
strcpy(ss->name, "abc");
transferFunction(ss, 0);
My goal is to have the randoms[index] having the struct's data as another function is going to read from it, as shown below, but I am unable to retrieve the struct data correctly, it gives me some garbage value
void readFunction() {
struct *SomeStruct ss = malloc(sizeof(struct SomeStruct));
memcpy(ss, &randoms[index], sizeof(struct SomeStruct));
printf(ss->name);
}
Does anyone knows how to solve this problem? Thank you very much!!!
You can not "copy in to a void".
A void * can contain a memory address, but does not contain any information about the size of the data at that address.
Also, it can not contain any data, only an address!
In this line:
void *randoms[10];
You create an array that can hold 10 addresses.
You never initialize this array, so it will start out all zeroes (this only works for global variables in C).
You can put the address of your structure in to the array, like so:
random[0] = (void*)ss;
However, this does not transfer any data, so if you free the original structure (ss) your data is gone, and the address in random[0] is illegal.
If you want to transfer data you need to create array of struct SomeStruct or you need to allocate another SomeStruct, store its address in random[0] then memcpy to that address.
void transferFunction(void* data, int size, int index)
{
randoms[index] = malloc(size);
if (randoms[index] != NULL) {
memcpy(randoms[index], data, size);
}
}
Your code has some problems:
struct *SomeStruct ss = ... should be struct SomeStruct *ss =.
You are not cheking the return value of malloc() (which may fail).
You are not freeing ss allocated with malloc(). You should call free() on ss.
My goal is to have the randoms[index] having the struct's data
Lev M.'s answer already answers this part.
as another function is going to read from it
Simply assign your void pointer to a SomeStruct pointer:
void readFunction(int index)
{
if (index >= 10) // Index out of range
return;
struct SomeStruct *ss = randoms[index];
printf("%s\n", ss->name);
}

A pointer to the array in a struct

The first parameter of qsort requires a pointer to the array ...
How could I pass the pointer in this case?
typedef struct apData {
char ssid[32];
sint8 rssi;
AUTH_MODE authmode;
char bssid[18];
int32_t channel;
uint8 is_hidden;
} AP;
//BSSs SCANNED
typedef struct {
bool scanInProgress = NOT_SCANNING;
AP **apData;
int numAPs;
} Scan;
static Scan scanAPs;
...
The problem is here in passing the first parameter ...
I don't understand why I'm getting trash in the compareRSSI() function
qsort(scanAPs.apData, scanAPs.numAPs, sizeof(struct apData), compareRSSI);
...
int compareRSSI(const void *bss1, const void *bss2) {
int firstAP = ((struct apData *)bss1)->rssi;
int secondAP = ((struct apData *)bss2)->rssi;
return (secondAP - firstAP);
}```
You're passing to qsort a pointer to an array of pointers (apData is of type AP**), but you're saying that each element of the array is sizeof(struct apData) (as if it were an array of structures). So which is it?
You didn't show how you assigned scanAPs.apData a value, and you didn't show where you allocated storage for the elements of the array to be sorted. So, unfortunately, it's unclear if you intended to be sorting an array of pointers or if you intended to have an array of apData structures.
If the type declaration is correct and you have an array of pointers...
Since the type of apData is AP **, then you would have had an array of pointers to structures somewhere. In which case your sort call should have looked like:
qsort(scanAPs.apData, scanAPs.numAPs, sizeof(struct apData*), compareRSSI);
Note that the sizeof indicates that each element of the array is a pointer.
If the type declaration is wrong and you have an array of structures...
If it's the type that is wrong, then you need to change the type of apData to just AP*, and set it equal to the pointer to the first structure in the array. You'll need to assign an appropriate value somewhere and verify that you allocated storage for the array correctly too.
Do not use a C-style cast when assigning apData a value because the compiler will ensure that you have the right type.
Here's, My solution! these guys helped me a lot.
link!
qsort(scanAPs.apData, scanAPs.numAPs, sizeof(struct apData*), compareRSSI);
...
int compareRSSI(const void *bss1, const void *bss2) {
struct apData **firstAP = (struct apData **)bss1;
struct apData **secondAP = (struct apData **)bss2;
return ((*secondAP)->rssi - (*firstAP)->rssi);
}

Assigning Arrays inside a Struct to a new Struct with Arrays

So I have a struct with arrays inside it like so:
struct struct1 {
unsigned char data1[32];
unsigned char data2[32];
char *id;
};
and a second struct defined as
typedef struct
{
uint8_t id;
uint8_t data1[32];
uint8_t data2[32];
} struct2;
Struct1 with data already inside it is passed to me via a function like so:
bool func1(struct struct1 * const struct1)
and I need to create a NEW struct2 and pass all the data from struct1 into it.
I thought I could just assign the pointers like so
struct2 *new_struct;
new_struct->id = struct1->id;
new_struct->data1 = struct1->data1;
new_struct->data2 = struct1->data2;
but I guess array pointers in C cannot be changed (or at least that's what I got from reading up on it).
So how do I create a new struct2 and pass the data I need into it from struct1?
array pointers in C cannot be changed
There is no such thing as an "array pointer". Either you have an array, or you have a pointer.
In your case data1 and data2 are arrays, so there is no pointer you could have reassigned. Your only choice is to copy the data stored in the arrays from one struct to the other.
You can use simple assignment (=) between struct variables of the same type, but in your case you have different types, so you need to copy each member separately. The easiest way to do that is to use memcpy (from <string.h>).
#include <string.h>
// ...
struct2 new_struct;
new_struct.id = *struct1->id;
memcpy(new_struct.data1, struct1->data1, sizeof new_struct.data1);
memcpy(new_struct.data2, struct1->data2, sizeof new_struct.data2);
Notes:
new_struct is not a pointer here. In your example you dereference an uninitialized pointer, which has undefined behavior.
I dereferenced struct1->id because struct2.id is a single char, not a pointer. I assume this is what you want to happen.

How do you pass a typedef struct to a function?

At the moment I'm trying
void avg(everything)
But that gives me the error:
error: subscripted value is neither array nor pointer
And when I got this error earlier today it was because I wasn't passing a 2D array to the function properly. So I figure this is the same but I can't find the correct format to pass it in.
This is my typedef:
typedef struct structure
{
char names[13][9];
int scores[13][4];
float average[13];
char letter[13];
} stuff;
And this is my typedef array:
stuff everything[13];
In the function signature, you need to specify the type, not the specific name of a variable you want to pass in. Further, if you want to pass an array, you need to pass a pointer (you should probably be passing structs by pointers anyway, otherwise a copy of the data will be made each time you call the function). Hence you function should look like:
void avg(stuff* s);
However, C arrays also have no concept of length. Hence, you should always pass in the length of the array to the function:
void avg(stuff* s, size_t len);
You'd then call this as follows:
avg(everything, 13);
Also, if the function doesn't modify the data in any way, you should signify this by specifying that the parameter is const:
void avg(const stuff* s, size_t len);
A type introduced with typedef is an alias that can be used for a real type.
For example:
typedef struct some_struct { ... } some_type_name;
Now you can use some_type_name instead of struct some_struct.
So when declaring a function which takes a structure of this "type" you use the type like any other type:
void some_function(some_type_name var) { ... }
In some_function as defined above, you can use var like a normal structure variable.
To define a function taking an array (or a pointer) to this type, that's equally simple:
void some_function(some_type_name *pointer) { ... }

a way to copy a 2dimensional array into a struct array

I have this array filled up with characters in my maze.c file:
char normalMazeArray[6][12]; dynamically filled as mazeArray[row][column]
Now I want to pass what the array to the mazeArray that is located in my struct (maze.h)
my struct is called:
typedef struct {
char mazeArray;
} maze_t;
I have tried copying it as follows:
maze_t* maze;
char normalMazeArray[6][12]; // filled with info
typedef struct {
char mazeArray;
} maze_t;
maze->mazeArray = normalMazeArray;
however it is not working,
anyone who could help me?
The thing what you're trying to do is not exactly possible. There are two slightly different solutions you can use, though.
normalMazeArray is of type char [6][12] - it's an array. You can either copy its contents to the same type of array using memcpy():
typedef struct {
char mazeArray[6][12];
} maze_t;
memcpy(maze->mazeArray, normalMazeArray, sizeof(normalMazeArray));
or if your normalMazeArray persists throughout the lifetime of the program, you can assign a pointer to it in the structure:
typedef struct {
char (*mazeArray)[12];
} maze_t;
maze->mazeArray = normalMazeArray;
Wait, how??
First of all, maze is a pointer, so you can't have maze.mazeArray. Second of all, maze->mazeArray is of type char, while mazeArray is of type char**. No can do.
You should write a function which allocates char** array, and then strdups strings from mazeArray. Or, if you want ownership transfer, and not just copy, you could go like this:
typedef struct {
char** mazeArray;
} maze_t;
maze_t maze;
maze.mazeArray = mazeArray;

Resources