Pointer to pointer confusion - c

Edit: The reason queue is 2d is because I need a pointer of Command so that cmd can equal NULL. NULL == (void *). This is where I get confused though, and why I've come here. :)
To help try and figure out another problem I have in Python, I'm implementing a small test program in C. While I know a little, apparently I'm confused. I'm trying to write a simple queue to be used in asynchronous USB transfers. Something's not right with queue, as every command popped from the queue is the same. If I write queue[1024][0] as queue[1024][1] instead, the command alternates between two distinct commands, and the program crashes in command_thread_main. Apparently it doesn't notice that cmd should be NULL. Changing [1] any higher has no effect as far as I can tell. Any hints?
typedef struct Command {
void (*cb) (char *data, int size);
unsigned char *data;
int size;
} Command;
struct Command queue[1024][0];
int queueEnd = 0;
int queueStart = 0;
static void queue_push(void (*cb), unsigned char *data, int size) {
if (queueEnd >= 1024)
return;
queue[queueEnd]->cb = cb;
queue[queueEnd]->data = data;
queue[queueEnd]->size = size;
queueEnd++;
}
struct Command * queue_pop(void) {
if( queueStart > queueEnd )
return NULL;
return queue[queueStart++];
}
static void *command_thread_main(void *arg) {
struct Command *cmd;
while (!do_exit) {
if(locked) continue;
locked = 1;
cmd = queue_pop();
if(cmd != NULL)
cmd->cb(cmd->data, cmd->size);
}
}

I think you have a bug you need to fix before anything else. You have a 2D array of commands and have set one of those dimensions to zero!
struct Command queue[1024][0];
When you access queue you seem to treat it as a 1D structure. Should you declare it as :
struct Command queue[1024];

Don't you mean struct Command queue[1024];? (That is, no [0] or [1] or whatever.)
In queue_pop I think you should test for queueStart >= queueEnd.
You should implement a circular array.
Right now you store the struct itself in an array, not pointers to it. That is sensible. You'll need to change -> to . though:
queue[queueEnd].cb = cb;
queue[queueEnd].data = data;
queue[queueEnd].size = size;
(And hence queue_pop should return a variable of type struct Command (not struct Command *), and the main code should also be updated accordingly.)
Of course you can also pass pointers around, but with such a small struct/queue there's no actual need.

As others have pointed out, that 2D queue is definitely wrong. You need a 1D queue, and I suspect that what you want is an array of pointers:
Command * queue[1024];
I reommend you go a way and think about the problem a bit, draw some diagrams and then come back with clearer code and question.

Another problem is that you've declared queue as an array of structs, but you're using it as an array of pointers to structs by using the dereferencing -> operator instead of the membership . one.
I don't mean to sound snarky, but compiler warning flags (-Wall for gcc) are your friends.

Related

general array printer function in c

I've those two structs :
typedef struct
{
char* name;
int flightCount;
Flight** flightArr;
LIST dateList;
int flightsSorted;
}Airline;
typedef struct
{
Airport* airportsArr;
int airportsCount;
}AirportManager;
and I need to write a general printer for both arrays (one is struct array and the other is pointer array).
I know that general printer should look like that:
void generalArrayFunction(const void* pArr, const int size, int sizeOfElement, void(*printer)(const void*))
{
for(int i=0;i<size;i++)
printer((char*)pArr + i * sizeOfElement);
}
and it's work great with the regular array which I print with the following line:
generalArrayFunction(manager.airportsArr,manager.airportsCount,sizeof(manager.airportsArr[0]),printAirport);
but with the pointer array I can't use the same logic and I dont know what should I do.the following line prints one struct but the second one messed up.
generalArrayFunction(*pComp->flightArr, pComp->flightCount, sizeof(pComp->flightArr[0]), printFlight);
any suggestions ?
If i got your intention right, In this code:
generalArrayFunction(*pComp->flightArr, pComp->flightCount, sizeof(pComp->flightArr[0]), printFlight);
sizeOfElement will be the size of a pointer because it's an array of pointers, you need to make another dereference to reach the struct and get the size, that's why the first struct is printing ok and the subsequent are not.
Try this:
generalArrayFunction(*pComp->flightArr, pComp->flightCount, sizeof((*pComp->flightArr)[0]), printFlight)

How to gain access to objects locked behind doublepointer? (C)

In a homework task I must gain access to object specifics (i.e pID, Code), which are located in a structure. However, I need to link my function with the objects first (**ppObjects), but since I am dealing with a doublepointer, I seem to be having an issue.
It is worth noting that when I tried the same commands but function was PrintNewObject(HeaderC* pStruct4) it worked fine - so I am guessing it is an issue with me having to use doublepointer when dealing with pStruct4.
I have provided the code that I have tried below. While compiling it shows no error, but upon trying to print something from it, it says that obj is a nullpointer.
The function that I would like to link with ppObjects.
int InsertNewObject(HeaderC** pStruct4){
HeaderC* testinH;
for (testinH = *pStruct4; testinH != NULL; testinH = testinH->pNext)
{
int count = 0;
while (count < 26) //one for every letter in the alphabet, as ppObjects is an array
{
Object9* obj;
obj = (Object9*)testinH->ppObjects[count]; //the line that does not seem to properly define
printf("%lu", obj->Code); //running this line crashes my program
count++;
}
}
Header, where we can see that ppObjects is a doublepointer.
typedef struct headc
{
void **ppObjects; // Pointer to the array of pointers to objects.
// Objects may be of types Object1-10
char cBegin; // The first letter of ID of objects related to
// header is cBegin.
struct headc *pNext;
} HeaderC;
The object I was provided in the hometask is below. This is what I would get access to after defining
typedef struct ob9
{
char *pID;
unsigned long int Code;
Date3 *pDate3;
struct ob9 *pNext;
} Object9;
I get an error saying that obj is nullpointer when I try to print anything from obj.
If this is poorly worded, I am sorry. I tried my best to make this understandable yet not too long. Any help is appreciated!

allocate memory block and assign to a char array for send socket a memory block [duplicate]

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);

using pointer to an array

currently, I'm facing a problem with my code and my understanding of pointer. here's the code
struct command
{
int type;
int *input;
int *output;
union{
struct command *command[2];
char **word;
}u;
};
to my understanding, the instance struct command *command[2] is an array of pointer to array of command. So I allocate the array with these:
cur_command->u.command[0] = malloc(sizeof(struct command[2]));
So it give me a 2d array of command. However my teacher told me that struct command *command[2] is a pointer to an array command size 2. So cur_command->u.command[0] give the first command element instead of a pointer to a command array size two. My question is, how can I allocate the memory to develop this kind of behavior. thx
First off, I would suggest changing the name of the one variable to, e.g. cmd instead of command to reduce confusion. That is:
....
union{
struct command *cmd[2];
char **word;
}u;
....
Now, as a couple other comments have pointed out, cur_command->u.cmd is an array of two pointers to struct command. cur_command->u.cmd[0] is the first of the two pointers, and cur_command->u.cmd[1] is the second. In order to use either of them, they should be initialized to be pointers to actual struct command objects:
cur_command->u.cmd[0] = malloc(sizeof(struct command));
cur_command->u.cmd[1] = malloc(sizeof(struct command));
Then, you can use either one in the same way you use your cur_command, which is also a pointer to struct command. That is, you can set some of the fields:
cur_command->u.cmd[0]->type = 1;
....
Don't forget to free memory when you're done with it:
free(cur_command->u.cmd[0]);
free(cur_command->u.cmd[1]);
Since the structure is recursive, you may need some recursive code to correctly free all the memory, depending on how deeply you chain these things together...
Also note, that in your posted code (malloc(sizeof(struct command[2]))), the sizeof(...) bit isn't doing what you think it is. I'm not entirely sure it should even compile, as you can't treat a struct as an array like that...

Variable length arrays in struct

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);

Resources