NOTE: I've re written the original question to make it much more clear.
I have a function called
VcStatus readVcard( FILE *const vcf, Vcard **const cardp )
vcf is an open file I will read, and cardp is a pointer to the start of an array of cards.
a file will have multiple cards in it.
readVCard reads the file a line at a time, and calls the function parseVcProp to indentify keywords in the line, and assign them to the appropriate place in a structure.
Here are the structures
typedef struct { // property (=contentline)
VcPname name; // property name
// storage for 0-2 parameters (NULL if not present)
char *partype; // TYPE=string
char *parval; // VALUE=string
char *value; // property value string
void *hook; // reserved for pointer to parsed data structure
} VcProp;
typedef struct { // single card
int nprops; // no. of properties
VcProp prop[]; // array of properties
} Vcard;
typedef struct { // vCard file
int ncards; // no. of cards in file
Vcard **cardp; // pointer to array of card pointers
} VcFile;
So a file contains multiple cards, a card contains multiple properties, etc.
The thing is, a single card can any have number of properties. It is not known how many until you are done reading them.
Here is what I do not understand.
How must I allocate the memory to use parseVcProp properly?
Each time I call parseVcProp, i obviously want it to be storing the data in a new structure, so how do i allocate this memory before hand? Do i just malloc(sizeof(VcProp)*1)?
Vcard *getcards(int n) {
Vcard *c = malloc(sizeof(Vcard) + sizeof(VcProp) * n);
c->nprops = n;
return c;
}
You really need to show us the particular line that's producing the error.
With that said, for a structure like vcard that contains a flexible array member, you cannot create variables of that type. You can only create pointer variables. For instance:
vcard *vc = malloc(sizeof(vcard) + n*sizeof(VcProp));
At this point, vc->prop[0] through vc->prop[n-1] are valid array elements (each has type VcProp).
Note that a flexible array member is an array, not a pointer.
Sorry for the confusion everyone.
I figured out my error.
The reason things were going wacky is because propp is an output pointer, not a input pointer
I was trying to use Vcard->prop as a passing argument, when I actually had to just create my own, and send the address of it.
Related
I'm writing an application in C (as a beginner) and I'm struggling with getting corrupted data inside a struct that contains a variable length array. I found similar issues described in forum posts on cprogramming.com and also on cert.og/secure-coding. I thought I'd had found the right solution, but it seems not.
The struct looks like this;
typedef struct {
int a;
int b;
} pair;
typedef struct {
CommandType name;
pair class;
pair instr;
pair p1;
pair p2;
pair p3;
CommandType expected_next;
char* desc;
int size;
pair sw1;
pair sw2;
pair* data;
} command;
With the problematic one being "command". For any given instance (or whatever the correct phrase would be) of "command" different fields would be set, although in most cases the same fields are set albeit in different instances.
The problem I have is when trying to set the expected_next, name, sw1, sw2, size and data fields. And it's the data field that's getting corrupt. I'm allocating memory for the struct like this;
void *command_malloc(int desc_size,int data_size)
{
return malloc(sizeof(command) +
desc_size*sizeof(char) +
data_size*sizeof(pair));
}
command *cmd;
cmd = command_malloc(0, file_size);
But when I (pretty) print the resulting cmd, the middle of the data field appears to be random garbage. I've stepped through with gdb and can see that the correct data is getting loaded into the the field. It appears that it's only when the command gets passed to a different function that it gets corrupted. This code is called inside a function such as;
command* parse(char *line, command *context)
And the pretty-print happens in another function;
void pretty_print(char* line, command* cmd)
I had thought I was doing things correctly, but apparently not. As far as I can tell, I construct other instances of the struct okay (and I duplicated those approaches for this one) but they don't contain any variable length array in them and their pretty-prints looks fine - which concerns me because they might also be broken, but the breakage is less obvious.
What I'm writing is actually a parser, so a command gets passed into the parse function (which describes the current state, giving hints to the parser what to expect next) and the next command (derived from the input "line") is returned. "context" is free-d at the end of the parse function, which the new command getting returned - which would then be passed back into "parse" with the next "line" of input.
Can anyone suggest anything as to why this might be happening?
Many thanks.
When you allocate memory to structure, only a pointer size gets allocated to *desc. You must allocate memory to the space (array contents) desc points to, as someone already pointed out. Purpose of my answer is to show slightly different way of doing that.
Since having a pointer *desc increases structure size by a word (sizeof pointer), you can safely have a variable length array hack in you structure to reduce structure size.
Here's how your structure should look like, notice that desc[] has been pulled down to the end of structure :
typedef struct {
CommandType name;
pair class;
pair instr;
pair p1;
pair p2;
pair p3;
CommandType expected_next;
int size;
pair sw1;
pair sw2;
pair* data;
char desc[];
} command;
Now,
1. Allocate memory for command which includes array size also :
command *cmd = malloc(sizeof(command) + desc_length);
Use desc :
cmd->desc[desc_length -1] = '\0';
This hack works only if member is at the end of structure, saves structure size, saves pointer indirection, can be used if array length is structure instance specific.
You have to allocate desc and data separately.
When you allocate your struct command *cmd, memory is allocated for your pointers of decs and data. Desc and data have to be malloced separately.
So allocate your command
command *cmd = malloc(sizeof(command));
then allocate memory for data or desc
example for desc:
cmd->desc = malloc( sizeof(char )*100);
I have two structs in a library I cannot change. p.e:
struct{
uint8_t test;
uint8_t data[8];
}typedef aStruct;
struct{
uint8_t value;
uint8_t unimportant_stuff;
char data[8];
}typedef bStruct;
aStruct a;
bStruct b;
In my application there is a process that permantently refreshs my aStruct's.
Now I have a buffer of bStruct's I want to keep updated as well.
The data[] array is the important field. I don't really care about the other values of the structs.
I already made sure, that on that specific system where the code runs on, a "char" is 8Bits as well.
Now I'd like to make the "b.data" array point to exactly the same values as my "a.data" array. So if the process refreshs my aStruct, the values in my bStruct are up to date as well.
Therefore that in C an array is only a pointer to the first element, I thought something like this must be possible:
b.data = a.data
But unfortunately this gives me the compiler-error:
error: assignment to expression with array type
Is there a way to do what I intend to do?
Thanks in advance
Okay, according to the input I got from you guys, I think it might be the best thing to redesign my application.
So instead of a buffer of bStruct's I might use a buffer of aStruct*. This makes sure my buffer is always up to date. And then if I need to do something with an element of the buffer, I will write a short getter-function which copies the data from that aStruct* into a temporary bStruct and returns it.
Thanks for your responses and comments.
If you want b.data[] array to point to exactly the same values, then you can make data of b a char* and make it point to a's data.
Something like
struct{
uint8_t value;
uint8_t unimportant_stuff;
char* data;
}typedef bStruct;
and
b.data = a.data;
But, keep in mind, this means that b.data is pointing at the same memory location as a.data and hence, changing values of b.data would change values of a.data also.
There is another way of doing this. It is by copying all the values of a.data into b.data. Then, b.data would merely contain the same values as a.data, but it would point to different memory locations.
This can either be done by copying one by one. In a for loop for all the 8 elements.
Or, to use memcpy()
NOTE
Arrays cannot be made to point to another memory locations. As they are non modifiable l-value. If you cannot modify the structs, then you have to use the second method.
What you are asking is not possible when you can not modify the existing struct definitions. But you can still automate the functionality with a bit of OO style programming on your side. All of the following assumes that the data fields in the structs are of same length and contain elements of same size, as in your example.
Basically, you wrap the existing structs with your own container. You can put this in a header file:
/* Forward declaration of the wrapper type */
typedef struct s_wrapperStruct wrapperStruct;
/* Function pointer type for an updater function */
typedef void (*STRUCT_UPDATE_FPTR)(wrapperStruct* w, aStruct* src);
/* Definition of the wrapper type */
struct s_wrapperStruct
{
STRUCT_UPDATE_FPTR update;
aStruct* ap;
bStruct* bp;
};
Then you can can create a factory style module that you use to create your synced struct pairs and avoid exposing your synchronization logic to uninterested parties. Implement a couple of simple functions.
/* The updater function */
static void updateStructs(wrapperStruct* w, aStruct* src)
{
if ( (w != NULL) && (src != NULL) )
{
/* Copy the source data to your aStruct (or just the data field) */
memcpy(w->ap, src, sizeof(aStruct));
/* Sync a's data field to b */
sync(w); /* Keep this as a separate function so you can make it optional */
}
}
/* Sync the data fields of the two separate structs */
static void sync(wrapperStruct* w)
{
if (w != NULL)
{
memcpy(w->bp->data, w->ap->data, sizeof(w->bp->data));
}
}
Then in your factory function you can create the wrapped pairs.
/* Create a wrapper */
wrapperStruct syncedPair = { &updateStructs, &someA, &someB };
You can then pass the pair where you need it, e.g. the process that is updating your aStruct, and use it like this:
/* Pass new data to the synced pair */
syncedPair.update( &syncedPair, &newDataSource );
Because C is not designed as an OO language, it does not have a this pointer and you need to pass around the explicit wrapper pointer. Essentially this is what happens behind the scenes in C++ where the compiler saves you the extra trouble.
If you need to sync a single aStruct to multiple bStructs, it should be quite simple to change the bp pointer to a pointer-to-array and modify the rest accordingly.
This might look like an overly complicated solution, but when you implement the logic once, it will likely save you from some manual labor in maintenance.
As part of a school assignment, I am given a structure with a double pointer to another structure inside it. I will need to be able to access the members of the nested structure within a function, but am having no luck doing so.
Here is the code I have been given
#include<stdio.h>
#include <stdlib.h>
/*Given code, do not change */
typedef struct
{
char* ID;
char* PassWord;
}Account, *pAccount, **ppAccount;
typedef struct
{
unsigned int numAccounts;
ppAccount accounts;
}FleaBay,*pFleaBay;
void FleaBayInit(pFleaBay); /* Initialise the FleaBay instance */
int main(void)
{
FleaBay e;
FleaBayInit(&e); /* Call to the function */
return 0;
}
/* end of given code */
Here is my attempt:
void FleaBayInit(FleaBay *pFleaBay){ /* Initialise the FleaBay instance */
Account ac1 = {"test1", "test2"}, *pac1 = &ac1;
pFleaBay ->numAccounts = 0;
pFleaBay ->accounts = &pac1;
}
I'm having no trouble accessing the member within the non-nested struct, but I cannot figure out how to access the members of the nested Account structure. Thought that maybe I would need to create an Account object first, point to it, and assign the value of the pointer to the accounts member within pFleaBay, but when I test with printf("%s",pFleaBay->accounts);, I get some random characters.
In the structure
typedef struct
{
char* ID;
char* PassWord;
}Account, *pAccount, **ppAccount;
ppAccount is a pointer to a pointer, which is often used to represent a dynamic array of pointers.
In the second structure
typedef struct
{
unsigned int numAccounts;
ppAccount accounts;
}FleaBay,*pFleaBay;
you have the number of the accounts, which would be the number of the elements in the dynamic array. So, in your code you could access one of the accounts using the syntax pFleaBay->accounts[n]. This means that you would want to allocate an array of pointers in your function either using malloc or calloc.
pFleaBay->accounts = calloc(pFleaBay->numAccounts, sizeof(pAccount));
Then you can allocate each of the accounts.
In your FleaBayInit(), ac1 is a local variable, and pac1 is initialized as a pointer to ac1. As a local variable, ac1's lifetime is limited to one function call. After the function returns, ac1 no longer exists, and any pointer that points to it becomes invalid.
Moreover, FleaBay.accounts is an Account **, but you try to assign an Account * to it (pac1). Not only does that pointer become invalid when the function returns, it isn't even the correct type. This is actually odd; I don't see any reason why FleaBay.accounts should not be simply an Account *.
Edited to add:
On second thought, FleaBay.accounts could be an Account ** because it is meant to point to a dynamic array of Account *, as opposed to a dynamic array of Account. That would offer some advantages, particularly if Account objects must be independent of FleaBays.
In that case, the simplest way to initialize a FleaBay would probably be this:
void FleaBayInit(FleaBay *pFleaBay){ /* Initialise the FleaBay instance */
pFleaBay->numAccounts = 0;
pFleaBay->accounts = NULL;
}
Whether that is actually appropriate, however, depends on how you intend to implement other code that manipulates FleaBays -- especially code that adds or removes accounts.
I'm wondering for a solution to the below problem. Please help.
Problem:
struct s{
int a;
int b;
}st;
I want a function to initialize the values at runtime. The problem is that I want to make it generic, so I want to pass the member name as input to the function and get it initialized.
fun_init(char* mem, int val)
{
// Find offset of the member variable in struct 'st'
// Assign the value
}
One straight solution is to use string comparision on the member name. But if I happen to add some extra variables at a later time, I'll have to modify the function, which I don't want.
Hope I was able to frame the ques clearly.
Thanks
C does not provide a way to find a symbol by name. See this thread for more information.
The simplest solution here is to use an associative array.
Read this thread if you need to mix value-types. (In your example, all value types are int, so you might not need this.)
void fun_init(int *storage, int val) {
*storage = val;
}
void something_else(void) {
struct s {
int a;
int b;
} st;
fun_init(&st.a, 42);
}
However, if you need to dynamically determine the key name, you are doing something wrong. If you need to store key/value pairs, perhaps you would be interested in the hashtable.
I'm guessing you want to initialize struct from either user input or persistency.
A solution involves creating an associative array as mentioned by #Domi.
The array is filled with key/value pairs such as (const char*, unsigned).
The key is the name of struct member and the value is the offset from the start of the struct.
Each struct will need to have a function that initializes the above array. You can get an offset to a member via the offsetof macro.
This will NOT work with structs that have bit fields (sub byte named members).
I'm writing an application in C (as a beginner) and I'm struggling with getting corrupted data inside a struct that contains a variable length array. I found similar issues described in forum posts on cprogramming.com and also on cert.og/secure-coding. I thought I'd had found the right solution, but it seems not.
The struct looks like this;
typedef struct {
int a;
int b;
} pair;
typedef struct {
CommandType name;
pair class;
pair instr;
pair p1;
pair p2;
pair p3;
CommandType expected_next;
char* desc;
int size;
pair sw1;
pair sw2;
pair* data;
} command;
With the problematic one being "command". For any given instance (or whatever the correct phrase would be) of "command" different fields would be set, although in most cases the same fields are set albeit in different instances.
The problem I have is when trying to set the expected_next, name, sw1, sw2, size and data fields. And it's the data field that's getting corrupt. I'm allocating memory for the struct like this;
void *command_malloc(int desc_size,int data_size)
{
return malloc(sizeof(command) +
desc_size*sizeof(char) +
data_size*sizeof(pair));
}
command *cmd;
cmd = command_malloc(0, file_size);
But when I (pretty) print the resulting cmd, the middle of the data field appears to be random garbage. I've stepped through with gdb and can see that the correct data is getting loaded into the the field. It appears that it's only when the command gets passed to a different function that it gets corrupted. This code is called inside a function such as;
command* parse(char *line, command *context)
And the pretty-print happens in another function;
void pretty_print(char* line, command* cmd)
I had thought I was doing things correctly, but apparently not. As far as I can tell, I construct other instances of the struct okay (and I duplicated those approaches for this one) but they don't contain any variable length array in them and their pretty-prints looks fine - which concerns me because they might also be broken, but the breakage is less obvious.
What I'm writing is actually a parser, so a command gets passed into the parse function (which describes the current state, giving hints to the parser what to expect next) and the next command (derived from the input "line") is returned. "context" is free-d at the end of the parse function, which the new command getting returned - which would then be passed back into "parse" with the next "line" of input.
Can anyone suggest anything as to why this might be happening?
Many thanks.
When you allocate memory to structure, only a pointer size gets allocated to *desc. You must allocate memory to the space (array contents) desc points to, as someone already pointed out. Purpose of my answer is to show slightly different way of doing that.
Since having a pointer *desc increases structure size by a word (sizeof pointer), you can safely have a variable length array hack in you structure to reduce structure size.
Here's how your structure should look like, notice that desc[] has been pulled down to the end of structure :
typedef struct {
CommandType name;
pair class;
pair instr;
pair p1;
pair p2;
pair p3;
CommandType expected_next;
int size;
pair sw1;
pair sw2;
pair* data;
char desc[];
} command;
Now,
1. Allocate memory for command which includes array size also :
command *cmd = malloc(sizeof(command) + desc_length);
Use desc :
cmd->desc[desc_length -1] = '\0';
This hack works only if member is at the end of structure, saves structure size, saves pointer indirection, can be used if array length is structure instance specific.
You have to allocate desc and data separately.
When you allocate your struct command *cmd, memory is allocated for your pointers of decs and data. Desc and data have to be malloced separately.
So allocate your command
command *cmd = malloc(sizeof(command));
then allocate memory for data or desc
example for desc:
cmd->desc = malloc( sizeof(char )*100);