I have a structure named command that looks like this. The first value in the enum is AND_COMMAND
struct command
{
enum command_type type;
int status;
char *input;
char *output;
union
{
struct command *command[2];
char **word;
struct command *subshell_command;
} u;
};
When I call pthread_create I pass it a command in the form of a command_t (that is cast to (void *)).
typedef struct command *command_t;
My thread takes this (void *) command_t, casts it back (command_t) and tries to use the structure.
void execute_thread(void *c) {
command_t command = (command_t) c;
However when I pass a struct in to execute_thread the first values are zeroed out. If I have a command_type of SIMPLE_COMMAND and status of -1, when it's passed in to the thread the command_type is AND_COMMAND and status of 0. None of the other values in the struct are changed however. What's more curious is when this data mangling occurs. I was able to capture the phenomenon in gdb:
445 command_t command = (command_t) c;
(gdb) p *((command_t) c)
$6 = {type = SIMPLE_COMMAND, status = -1, input = 0x605370 "abc", output = 0x605390 "def", u = {
command = {0x6052e0, 0x0}, word = 0x6052e0, subshell_command = 0x6052e0}}
(gdb) n
(gdb) p *((command_t) c)
$7 = {type = AND_COMMAND, status = 0, input = 0x605370 "abc", output = 0x605390 "def", u = {command = {
0x6052e0, 0x0}, word = 0x6052e0, subshell_command = 0x6052e0}}
It appears that the structure pointed to by c doesn't change until casting it with (command_t) c; I am entirely confounded by this behavior. I didn't think that casting a pointer could change the values it pointed to. Could someone please point out, ha ha, what could be going on here? I would appreciate that very much.
What's more curious is when this data mangling occurs. I was able to capture the phenomenon in gdb:
The wording here leads me to believe that the problem isn't deterministic; ie., sometimes it doesn't happen, or it doesn't happen at the moment you happened to capture in gdb in the question.
If that's the case (and maybe even if it isn't), I suspect that you problem is that you're trashing the memory allocated to the struct command in the main thread (or whatever thread is creating the execute_thread() thread). You didn't show us the thread creation code, but if you use a local variable and pass the address of that to the created thread, then it can be tricky to make sure the local variable's lifetime doesn't expire before the the second thread gets around to using it. You might want to pass in a struct command that has been allocated on the heap:
struct command* thread_data = malloc(sizeof(struct command));
struct_command_init(thread_data);
pthread_create(/* ... */, thread_data);
// ...
and in the execute_command() thread:
void* execute_command(void* p)
{
struct command cmd = *(struct command*)p;
free(p);
// use cmd to get at the structure data passed in...
}
Keep in mind that the data referred to by various pointers insode the struct command also need to have their lifetime and ownership clearly managed, too.
Related
The values of pointers of a struct change after each call to printf.
I have the following structs:
struct block_meta_data
{
size_t size;
struct block_meta_data * next;
int isFree;
};
typedef struct block_meta_data block_meta_data;
struct list
{
block_meta_data* base;
block_meta_data* end;
};
typedef struct list list;
I defined a global variable of type list called blocks_list:
list blocks_list = {NULL, NULL};
and the main function looks like :
int main(void)
{
char a[] = "hello";
printf("%s\n", a);
return 0;
}
Now, using a debugger, I observe the values of both fields of the 'blocks_list' variable before the call to printf and they both have the value NULL:
After the call to printf, the values of both fields change to:
I tried printing the values of both end and base (without using a compiler) and the issue still remains:
list blocks_list = {NULL, NULL};
int main(void)
{
char a[] = "hello";
printf("%s\n", a);
printf("base = %p | end = %p\n", blocks_list.base, blocks_list.end);
return 0;
}
output :
hello
base = 0x555eed65d000 | end = 0x555eed65d000
Can someone explain why this is happening?
Can someone explain why this is happening?
There are a few possible explanations:
you are not telling us the whole story (provide MCVE) -- this is the most likely one
this is a debugging artifact -- your debugger is confused and shows something that isn't actually happening
the compiler detected that blocks_list is not actually used, and didn't allocate any storage for it (usually the compiler would also set location of blocks_list to 0, which would prevent debugger from displaying it).
Since you appear to be using Linux, note that you can tell where the value is overwritten using GDB watch points:
(gdb) watch -l blocks_list.base
(gdb) continue
# GDB will stop when blocks_list.base changes its value
this is driving me nuts, I've done my homework but for some reason here
for (int i = 0; i < room->num_of_challenges; i++) { // need a check
if (strcmp(room_to_enter, room->challenges[i].challenge->name) == 0) {
room->challenges[i].start_time = start_time;
room->challenges[i].visitor = malloc(sizeof(room->challenges[i].visitor));
room->challenges[i].visitor->current_challenge = malloc(sizeof(room->challenges[i].visitor->current_challenge));
*room->challenges[i].visitor->current_challenge = room->challenges[i];
*room->challenges[i].visitor->room_name = NULL;
*room->challenges[i].visitor->room_name = malloc(strlen(room_to_enter)+1);
strcpy(*room->challenges[i].visitor->room_name, room_to_enter);
inc_num_visits(room->challenges[i].challenge);
}
}
the program just crashes for some reason, at this point:
*room->challenges[i].visitor->room_name = malloc(strlen(room_to_enter)+1);
it's a 3 pages code with headers for each, and each page is about 300 line, so I can't post them all, also here are the structs:
struct SChallengeActivity;
typedef struct SVisitor
{
char *visitor_name;
int visitor_id;
char **room_name;
struct SChallengeActivity *current_challenge;
} Visitor;
typedef struct SChallengeActivity
{
Challenge *challenge;
Visitor *visitor;
int start_time;
} ChallengeActivity;
typedef struct SChallengeRoom
{
char *name;
int num_of_challenges;
ChallengeActivity *challenges;
} ChallengeRoom;
We can't edit the struct because it's given by the homework like that, the thing is I tried to set this line to NULL, like so:
*room->challenges[i].visitor->room_name = NULL;
and it still crashes at that line too, for some reason it can't reach that field in the struct.
Note: ignore the coding, I know I should check the malloc after each line, but for now I want it to work, I've been up all night to get it to work, and I couldn't, any help please ?
Thank you
When allocating memory for the visitor, you are only allocating the aize of a pointer. The visitor field inside your challenge is only a pointer to a Visitor. Thus you are not allocating enough memory. You should use:
malloc(sizeof(Visitor))
To get the real size of the Visitor structure and allocate ample space.
Also, setting pointers to null before allocating is useless. The call to malloc() will overwrite them.
Also,
*room->challenges[i].visitor->room_name = NULL;
room_name is a char** (pointer-to-pointer), which means it's still a pointer, and you dereference it before it's set.
Not sure why it needs to be a pointer-to-pointer, but if it needs to be, then you first have to allocate memory for one or more pointers (eg array):
room->challenges[i].visitor->room_name = malloc(sizeof(char*)*1);
*room->challenges[i].visitor->room_name = malloc(strlen(room_to_enter)+1);
...
typedef struct Oft{
int mode;
int refCount;
} OFT;
typedef struct proc{
struct proc *next;
int uss, usp;
int pid; // add pid for identify the proc
int status; // status = FREE|READY|RUNNING|SLEEP|ZOMBIE
int ppid; // parent pid
OFT *fd[10];
int kstack[1024]; // per proc stack area
}PROC;
How would I initialize and use my *fd[10] variable?
assume that I have
PROC *p;
Is this the correct way to initialize its *fd[10]?
for(i = 0; i < 10; i++)
{
p->fd[i] = (OFT *) malloc (sizeof(OFT));
(*p->fd)[0] = Some OFT object?
}
why is p->fd[i] always equal to null when I do the following checking?
if (p->fd[i] == NULL)
//Do sometiong
p->fd[i] = malloc(sizeof(OFT));
is correct, as long as you've provided space for p to point to, by using malloc() or by making it point to some PROC variable. Note you don't need to cast, since malloc() returns a void * which is cast to any type of pointer automatically. You should, however, check if malloc() returns NULL.
(*p->fd)[0]
is wrong and will result in a compiler error. If you have an OFT object named myoft; you can assign it just like you did with malloc; of course, since fd[x] is a pointer, you want to have the address of the object:
p->fd[x] = &myoft;
If you want to access one of the components of one of your OFTs, you could, for example, use
p->fd[x]->refCount++;
I can't answer the last question, why if (p->fd[i] == NULL) is always true, unless you provide a complete example of your code.
I'm new to development in VxWorks (using 6.8) and I've run into a situation where I need to pass the address of a struct to a function. Is it possible to create a struct from the interpreter shell? I have a hard copy of a VxWorks programmers guide that is based on v5.5 and it explicitly says that structs cannot be formed/created from the interpreter shell. Has this changed in later versions of VxWorks and if so, how would I make a struct from the command line.
As a VxWorks newb, I was hoping to run the command
myStruct = {msg1 ="hi", msg2 = "hello" }
and then use the struct in another statement like
printf("%s\n", myStruct.msg1)
If a struct cannot be created in the interpreter like above, what options can I pursue in order to get the printf statement to print "hi" or "hello" by accessing a member within the struct?
No, as of 6.9 the vxWorks C shell does not support structs. See the C Interpreter Limitations section of the Wind River Workbench Host Shell User's Guide. The shell uses a symbol table that does not track the types of its symbols, and you cannot define types on the command line.
To get the same behavior, you could allocate memory for a struct and then fill it in by address. The size you allocate doesn't have to be exact, but your memory offsets do. Your example is easy because you have only 2 pointers, and your struct wouldn't have any padding. If you are on a 32-bit processor, then the size of a pointer is 4 bytes. So the first pointer is at offset 0, 1, 2, and 3, and then the 2nd pointer starts at offset 4.
E.g.,
-> mystruct = malloc(50);
New symbol "mystruct" added to kernel symbol table.
mystruct = 0x3a320a0: value = 63949520 = 0x3cfcad0
-> mystruct[0] = "hi";
0x3cfcad0: value = 61030776 = 0x3a364a0
-> mystruct[4] = "hello";
0x3cfcae0: value 61040928 = 0x3a36920 = ' '
-> printf("%s\n", mystruct[4]);
hello
value = 6 = 0x6
Things would get tricky as your struct got larger, and if there were padding. E.g., struct { char, int } could have a size of 6 or 8 depending on your processor's alignment requirements, so you'd have to be aware of that when trying to get the offset of the int. If it got too complicated, you could compile helper functions in your code that perhaps look like this pseudo code:
struct st { char a; int b; char *c; };
struct st *make_me_a_struct(char a, int b, char *c)
{
struct st *newstruct = malloc(sizeof(st));
newstruct->a = a;
newstruct->b = b;
newstruct->c = c;
return newstruct;
}
for instance this code:
struct test{
int ID;
bool start;
};
struct test * sTest;
void changePointer(struct test * t)
{
t->ID = 3;
t->start = false;
}
int main(void)
{
sTest->ID = 5;
sTest->start = true;
changePointer(sTest);
return 0;
}
If I was to execute this code, then what would the output be? (i.e. if I pass a pointer like this, does it change the reference or is it just a copy?)
Thanks in advance!
Your program doesn't have any output, so there would be none.
It also never initializes the sTest pointer to point at some valid memory, so the results are totally undefined. This program invokes undefined behavior, and should/might/could crash when run.
IF the pointer had been initialized to point at a valid object of type struct test, the fields of that structure would have been changed so that at the end of main(), ID would be 3. The changes done inside changePointer() are done on the same memory as the changes done in main().
An easy fix would be:
int main(void)
{
struct test aTest;
sTest = &aTest; /* Notice the ampersand! */
sTest->start = true;
changePointer(sTest);
return 0;
}
Also note that C before C99 doesn't have a true keyword.
The only question is why do you need a test pointer in a global name space? Second is that you do not have any memory allocation operations. And you have a pointer as an input parameter of your function. Therefore structure where it points to will be changed in "changePointer".
1) First thing your code will crash since you are not allocating memory for saving structure.. you might need to add
sText = malloc(sizeof(struct test));
2) After correcting the crash, you can pass structure pointer and the changes you make in changePointer function will reflect in main and vizeversa..
3) But since you are not printing anything, there wont be any output to your program..