Tearing my hair out on this one.
So I have 2 structs:
struct character_data{
(a billion other varibles);
struct skill_stuff *skillstats;
};
struct skill_stuff{
int skill;
int skillname;
};
My problem is, I'm trying to access data in *skillstats, but I crash every time.
void this_skill(character_data ch){
int skill = 1;
ch->skillstats->skill = skill;
}
Even trying to just access it in a print function, using ("%d", ch->skillstats->skill) crashes it. I'm at my wit's end.
Related
Thanks for all the help, I was just getting the order of operations wrong and I was forgetting that I don't need & before a pointer, as that is done automatically. My goal was to find a shorter way than using &(*head) and I thought that only head might do it somehow as I got confused using the debugger.
Just a quick question guys, nothing major.
This is my problematic function in its working state:
void getInput_stock(stock **head, char fgr, char bgr)
{
scanStr(&(*head)->name, 60);
}
This is what scanStr looks like:
int scanStr(char *input, int limit);
I've been dealing with structs since quite some time but they still confuse me. I made a breakpoint at scanStr(&(*head)->name, 60); and I checked variables &(*head) and head, they were both returning the same address. But when I try to use scanStr(head->name, 60); instead of the example given at the top of the post, I get an error left of '->name' must point to struct/union. I believe it IS a pointer to a struct. Why am I getting this error? I mean isn't &(*var) the same as var?
struct stockNode {
int ID;
int price[2];
int qty;
int date[3];
unsigned int number[2];
char name[60];
char nameProv[60];
char town[14];
char street[30];
struct stockNode *next;
};
typedef struct stockNode stock;
As name is a member of the stock struct - accessing one of its members is simply using the -> operator when the variable is a pointer to the struct.
In your usage
void getInput_stock(stock **head, char fgr, char bgr)
{
scanStr(&(*head)->name, 60);
}
the head is a pointer to a stock pointer - this means first reference to it (*head) becomes a pointer to stock, therefore accessing its member needs simple -> operator usage.
Your function should be
void getInput_stock(stock **head, char fgr, char bgr)
{
scanStr((*head)->name, 60);
}
A project in C is being forced upon me. I do not have much C knowledge, but I'm assuming the answer is simple.
struct s1 {
char *text;
int num;
};
struct s2 {
struct s1 vals[5];
int numbers;
};
Assume s2 is already populated. How do access num from s1? I was assuming I would do something like
struct s2 temp;
//temp is populated somehow, doesn't matter in the case
printf("%d\n", temp.vals[0]->num);
but that doesnt work. Any suggestions?
Use temp.vals[0].num. The -> operator can only be used if you are using a pointer to a struct. You are using a struct directly.
I am currently working on a text based game in C and I'm having a problem altering values when certain events happen. Here is some of my data structure code:
typedef struct player {
int maxhealth;
int curhealth;
int in_combat;
monster c_enemy;
char *class;
char *condition;
rooms c_room;
inventory i;
stats stats;
} player;
Now, I think my problem is that I currently have c_room (Current Room) as a rooms, instead of a pointer to a rooms. This affects me later because I need to alter things like n_monsters within the struct rooms for the current room. However, when I modify it by doing p.c_rooms.n_monsters -= 1; I'm not sure it alters the actual value of n_monsters for the room that I should be referring to. I've tested this by leaving a room when n_monsters is 0, and then coming back to see that it's back at 1, the default value.
So yea, how would I point to right room?
Just:
typedef struct player {
int maxhealth;
int curhealth;
int in_combat;
monster c_enemy;
char *class;
char *condition;
rooms *c_room; // Like this?
inventory i;
stats stats;
} player;
// And then the assignment would look like:
c_room = *rooms[3]; <- an array of rooms for the dungeon in the game.
Assuming that c_room is a plain struct and not a pointer then you are right.
If you have
struct A {
int v;
};
struct B {
struct A a;
}
A a;
a.v = 3;
B b;
b.a = a;
This will actually copy the content of a inside B.a since they are assigned by value. They will be two different A, any modification to one of them won't be reflected on the other.
In your situation I would do something like:
struct Room {
// whatever
}
struct Room rooms[MAX_ROOMS];
struct Player {
struct Room *room;
}
Player p;
p.room = &rooms[index];
Now you will be able to correctly reference to room by p->room, it will be just a pointer to the actual room.
This code:
extern void *malloc(unsigned int);
struct Box {
int x, y ,w, h;
};
struct Wall {
char color[15];
struct Box *boxes[20];
};
int main(int argc, const char *argv[])
{
struct Wall *mywall = malloc(sizeof(struct Wall));
struct Box *myboxes[] = mywall->boxes;
return 0;
}
gives me invalid initializer error at line 14. What I am trying to do, is to get a copy of array of struct pointers, which are in a different struct.
Ouch; there are a number of problems here.
extern void *malloc(unsigned int);
Don't do that; use #include <stdlib.h> because that will be correct and what you wrote is typically incorrect (the argument to malloc() is a size_t, which is not necessarily an unsigned int; it might be unsigned long, or some other type).
struct Box {
int x, y ,w, h;
};
Apart from erratic space, struct Box is OK.
struct Wall {
char color[15];
struct Box *boxes[20];
};
And struct Wall is OK too.
int main(int argc, const char *argv[])
You aren't using argc or argv, so you'd be better using the alternative declaration of:
int main(void)
Original code again:
{
struct Wall *mywall = malloc(sizeof(struct Wall));
This allocates but does not initialize a single struct Wall. Of itself, it is OK, though you should check that the allocation succeeded before you use it. You also need to worry about allocating the struct Box items that the elements of the array will point to.
struct Box *myboxes[] = mywall->boxes;
You've got a minor catastrophe on hand here. You can't copy arrays like that. You haven't checked that you've got an array. Ignoring the error checking, you are stuck with one of:
struct Box *myboxes[] = { &mywall->boxes[0], &mywall->boxes[1], ... };
or:
struct Box **myboxes = &mywall->boxes;
I'm not convinced that you'd want the second version, for all it's shorter.
return 0;
I like to see return 0; at the end of main(), even though C99 allows you to omit it.
}
How about:
struct Box **myboxes = mywall->boxes;
?
Then you can do stuff like:
for ( int i = 0 ; i < 15 ; i++ )
mywall->boxes[i] = malloc(sizeof(Box));
Box* x = myboxes[1];
As the code is now, mywall->boxes isn't initialized.
NOTE: just re-read the question - this won't return a copy of the array, but point to the same location. There's no short solution for a copy without using memcpy or just copying the structs.
I'm beginning to learn about the use of structs in C. It's challenging and enjoyable. Needless to say I've encountered a problem I can't seem to figure out. I'm trying to make a flexible struct array as a member of another struct but I'm getting an error:
invalid use of flexible array
What am I doing wrong?
#define NUM_CHANNELS 4
struct channelStruct {
float volume;
uint mute;
};
struct enginestruct
{
float bpm;
int synctimeinbeats;
int synctimeinsamples;
int currentbeat;
int oneBeatInSamples;
int samplerate;
struct channelStruct channels[];
};
struct enginestruct engine, *engineptr;
struct channelStruct channel, *channelptr;
-(void) setupengine
{
engineptr = &engine;
engineptr->oneBeatInSamples = 22050;
engineptr->samplerate = 44100;
struct channelStruct *ch = (struct channelStruct *) malloc (
NUM_CHANNELS*sizeof(struct channelStruct) );
//error occurs here
engineptr->channels = ch;
}
EDIT 1
It's something like this I am trying to achieve
flexible length struct array inside another struct using C
EDIT 2*
O.K so I seem to be approaching the creation of a variable sized array of struct the wrong way. I have 2 things that I'm trying. The first I know works for sure. The second I would just like if somebody could sanity check it for me. I'm still learning about pointers and would like to know if A is the same as B. B would be my preferred method but I don't know if its correct. I'm confident about a because when I debug channels i see channel[0],channel[1]channel[2] etc. But I'm not so confident about B because when I debug it I only see an address to memory and the variables of channel struct listed.
A
// pretty sure this is o.k to do but I would prefer
// not to have to set the size at compile time.
struct enginestruct
{
float bpm;
int synctimeinbeats;
int synctimeinsamples;
int currentbeat;
int oneBeatInSamples;
int samplerate;
channel channels[NUM_CHANNELS]; //is this technically a pointer?
};
B
//I'm not sure if this is valid. Could somebody confirm for me if
//it is allocating the same amount of space as in A.
struct enginestruct
{
float bpm;
int synctimeinbeats;
int synctimeinsamples;
int currentbeat;
int oneBeatInSamples;
int samplerate;
channel *channels;
};
//This only works if channel in the engine struct is defined as a pointer.
channel * ar = malloc(sizeof(*ar) * NUM_CHANNELS);
engineptr->channels = ar;
**EDIT 3****
Yep they are the same. Not sure when you would use one over the other tho
channel channels[NUM_CHANNELS];
Is Equal To :)
struct enginestruct
{
float bpm;
int synctimeinbeats;
int synctimeinsamples;
int currentbeat;
int oneBeatInSamples;
int samplerate;
channel *channels;
};
channel * ar = malloc(sizeof(*ar) * NUM_CHANNELS);
engineptr->channels = ar;
Edit
I think I remember now what the problem is. When you declare a struct with a flexible array as it's last member it's doing something completely different than what you think.
struct channelStruct channels[];
is NOT a pointer, it is an in place array which is contiguous with the struct.
The way this is intended to be used is to lay the struct over an existing block memory. For instance, this is useful in networking when you have a packet with variable length data. So you might do something like:
struct mydata {
// various other data fields
int varDataSize;
char data[];
}
When you receive a packet you cast a pointer to the data to a mydata pointer and then the varDataSize field tells you how much you've got. Like I said, the thing to remember is that it's all one contiguous block of memory and data is NOT a pointer.
Old Answer:
I think that's only allow in the C99 standard. Try compiling with the -std=c99 flag.
Also, see this thread, Variable array in struct
Also see this SO post: Flexible array members in C - bad?
I am not an expert in this C feature but my common sense tells me that you cannot define objects of the type struct enginestruct, only pointers. This regards the engine variable in the following line:
struct enginestruct engine,*engineptr;