Reputation: 197
I'm having problems with const char array being stored to a struct, then when calling the value from a struct I don't always get the expected value.
Below is the code:
typedef struct
{
char *update_type;
char *transaction;
} TickType;
In a thread I have:
const char tx_types[] = "INV/ADD/MOD/DEL/RPL";
const char upd_types[] = "INS/OVR/MOV/DEL";
tick->transaction = &tx_types[4*upd.xpbu_transaction_type];
tick->update_type = &upd_types[4*upd.xpbu_update_type];
This upd.xpbu_transaction_type and this upd.xpbu_update_type return ints (0-4) and (0-3) respectively. In another thread we have printing to file:
fprintf(out, "%3.3s/%3.3s:\n",tick->transaction, tick->update_type);
fflush(out);
The problem is when checking out the output file I see the following:
+MOD/DEL:
+ / Â +:
+MOD/DEL:
+MOD/ :
/@Ea:
/<90>Ea:
/Ã Ea:
/0Fa:
/ :
So as you can see it is only right sometimes.
I'm sure my mistake is in the struct assignment. Unfortunately I can not offer a better look into the code due to it being proprietary software.
Upvotes: 0
Views: 2068
Reputation: 3564
Your code doesn't check that upd.xpbu_transaction_type or upd.xpbu_update_type is within the proper ranges.
Also you need to use a Mutex or something for thread safety.
Also it is not sufficiently clear which memory region these strings are actually stored in. Different environments have different rules regarding where const strings are going to be located. Make sure it is in global memory that is always accessible by both threads of execution. The easiest way to ensure this is to define the strings as const outside any function. If it must be in a function it has to be declared static const.
Depending upon your environment something as simple as this would suffice:
Thread A:
/* validate upd values, etc*/
switch (upd.xpbu_transaction_type)
{
...
default:
xpbu_tt = 0;
}
...
taskLock();
tick->transaction = &tx_types[4*xpbu_tt];
tick->update_type = &upd_types[4*xpbu_ut];
taskUnlock();
Thread B:
While (1)
{
...
taskLock();
t = tick->transaction;
u = tick->update_type;
taskUnlock();
fprintf(out, "%3.3s/%3.3s:\n",t,u);
fflush(out);
}
Upvotes: 0
Reputation: 36082
I suspect the problem is where you put the definitions of your arrays.
You should either put them in global address space or declare them static somewhere in order to be able to share the address to the strings between the tasks.
Alternatively as BlackBear suggested allocate memory and copy the substring in there.
Upvotes: 1
Reputation: 9340
First of all, is this tick
shared among threads? If so, then you have to protect the assignment to its members in a critical section, otherwise there might be a chance when the variable is being printed, another thread is updating it, causing garbage while printing. I'm not sure about the thread safety of fprintf()
and fflush()
, you should find it out too because it could be another factor that affect.
Upvotes: 1
Reputation: 22979
You have to malloc both update_type and transaction then using strcpy and copy the important part. You also have to edit a bit your strings: "INV\x00ADD\x00MOD\x00DEL\x00RPL" and "INS\x00OVR\x00MOV\x00DEL"
Upvotes: 0