using pointer to an array - c

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...

Related

struct copy in c where struct are elements

Hi i have following situation
typedef struct
{
int a;
Name team[5];
Sport sport[5];
} School;
where Name and Sport are also structs,
typedef struct
{
char arry[20];
}Name;
typedef struct
{
char arry[20];
int tag;
}Sport;
then
School first_school, second_school;
I populate them individually, then at some point I do
first_school = second_school
But I step through code this line doesn't seem to work. How should I copy ?
But I step through code this line doesn't seem to work. How should I copy ?
It's entirely correct to copy struct like that
first_school = second_school; // valid
If it doesn't work as expected then the error is somewhere else. For example, you need to do strcpy() for string members.
Structures are values that can be assigned. They can contain arrays, which by themselves are not assignable, but being inside a struct makes it possible.
That code is fine, except you need to reverse the order of the declarations, since School references Name and Sport they must be declared first.
I tested it and it works just fine after reversing the declaration order, this prints hello:
int main(void) {
School foo, bar;
strcpy(bar.team[0].arry, "hello");
foo = bar;
printf("'%s'\n", foo.team[0].arry);
return 0;
}
There is probably something else wrong with your initialization of the second_shool, or you're failing to verify that it worked.
It will work for most members, but you have one that cannot be copied like that arry. You should copy one element at a time from the target to the destination instances.
Note that there are functions that take care of such copying like memcpy(). But you cannot copy an array by assignment like you do with an int or a struct actually.

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

How to make a shallow copy of entire structure? [duplicate]

I want to copy an identical struct into another and later on use it as a comparance to the first one. The thing is that my compiler gives me a warning when Im doing like this! Should I do it in another way or am I doing this wrong:
In header File:
extern struct RTCclk
{
uint8_t second;
uint8_t minute;
uint8_t hour;
uint8_t mday;
uint8_t month;
uint8_t year;
}
RTCclk;
In C file:
struct RTCclk RTCclk;
struct RTCclk RTCclkBuffert;
void FunctionDO(void)
{
... // Some Code
/* Copy first struct values into the second one */
memcpy(&RTCclk, &RTCclkBuffert, sizeof RTCclk);
}
For simple structures you can either use memcpy like you do, or just assign from one to the other:
RTCclk = RTCclkBuffert;
The compiler will create code to copy the structure for you.
An important note about the copying: It's a shallow copy, just like with memcpy. That means if you have e.g. a structure containing pointers, it's only the actual pointers that will be copied and not what they point to, so after the copy you will have two pointers pointing to the same memory.
Your code is correct. You can also assign one directly to the other (see Joachim Pileborg's answer).
When you later come to compare the two structs, you need to be careful to compare the structs the long way, one member at a time, instead of using memcmp; see How do you compare structs for equality in C?
copy structure in c you just need to assign the values as follow:
struct RTCclk RTCclk1;
struct RTCclk RTCclkBuffert;
RTCclk1.second=3;
RTCclk1.minute=4;
RTCclk1.hour=5;
RTCclkBuffert=RTCclk1;
now RTCclkBuffert.hour will have value 5,
RTCclkBuffert.minute will have value 4
RTCclkBuffert.second will have value 3
Also a good example.....
struct point{int x,y;};
typedef struct point point_t;
typedef struct
{
struct point ne,se,sw,nw;
}rect_t;
rect_t temp;
int main()
{
//rotate
RotateRect(&temp);
return 0;
}
void RotateRect(rect_t *givenRect)
{
point_t temp_point;
/*Copy struct data from struct to struct within a struct*/
temp_point = givenRect->sw;
givenRect->sw = givenRect->se;
givenRect->se = givenRect->ne;
givenRect->ne = givenRect->nw;
givenRect->nw = temp_point;
}
Your memcpy code is correct.
My guess is you are lacking an include of string.h. So the compiler assumes a wrong prototype of memcpy and thus the warning.
Anyway, you should just assign the structs for the sake of simplicity (as Joachim Pileborg pointed out).
memcpy expects the first two arguments to be void*.
Try:
memcpy( (void*)&RTCclk, (void*)&RTCclkBuffert, sizeof(RTCclk) );
P.S. although not necessary, convention dictates the brackets for the sizeof operator. You can get away with a lot in C that leaves code impossible to maintain, so following convention is the mark of a good (employable) C programmer.
I think you should cast the pointers to (void *) to get rid of the warnings.
memcpy((void *)&RTCclk, (void *)&RTCclkBuffert, sizeof RTCclk);
Also you have use sizeof without brackets, you can use this with variables but if RTCclk was defined as an array, sizeof of will return full size of the array. If you use use sizeof with type you should use with brackets.
sizeof(struct RTCclk)

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

C Structs: Problem Initializing? Valgrind Errors

Coding in C:
typedef struct {
char *string;
int one;
int two;
} Example;
... elsewhere:
Example *new = (Example *)malloc(sizeof(Example*));
new->string = strdup(otherstring); //no problem here
new->one = 5; //valgrind says that there is an invalid write of size 4.
My program runs fine, I just can't make valgrind happy. And that probably means I will have some other error elsewhere.
I guess I don't have to declare a pointer to the structure, (i.e., I could call "Example new" instead), but I'm stuck finding out how to allocate memory on the heap because I will need to access "new" from other parts of the program.
Am I making a mistake in the above few lines? Or is my error likely to be somewhere else? This is the first memory error that valgrind reports.
EDIT: accidentally had int *s instead of ints in my struct. Fixed.
I see various problems here. First of all, this:
Example *new = (Example *)malloc(sizeof(Example*));
doesn't allocate the right amount of memory (and you don't need the cast). You want this:
Example *new = malloc(sizeof(Example));
Then, you say this:
new->one = 5;
and that's assigning an int to an int*; that's not a good idea and valgrind rightly complains about it. If your struct is properly declared, then you want this:
new->one = malloc(sizeof(int)); /* The other malloc doesn't allocate this, you have to. */
*(new->one) = 5;
I suspect (as you say that everything works) that you really mean to declare your struct like this:
typedef struct {
char *string;
int one;
int *two;
} Example;
but there isn't enough information to be certain. Then you probably still have similar issues with new->two.
Example *new = (Example )malloc(sizeof(Example));
Should be:
Example *new = (Example *)malloc(sizeof(Example);
You have to allocate the whole struct not just a reference to it. Sometimes the program runs just because you get lucky.
Try this instead (just cut, paste, and run):
Example *new = (Example *)malloc(sizeof(Example)); //This is the correct method as pointed out by Bob, otherwise you're allocating only enough space to fit a memory location vs the struct
new->string = strdup(otherstring); //this is okay
new->one = (int*)malloc(sizeof(int));
*(new->one) = 5; //You want to assign the value 5 to the new->one memory location, not assign new->one pointer the value of 5!!!

Resources