For the following code:
#include<stdatomic.h>
int *sp;
int threadFunc()
{
int *p;
for(int i = 0; i < 10; i ){
p = __atomic_load_n(&sp i, __ATOMIC_SEQ_CST);
printf("Value loaded = %d from %p", *p, p);
}
return 0;
}
int main(int argc, char *argv[])
{
int a = 0;
sp = malloc(sizeof(int)*10);
if(sp == NULL){
printf("Not enough memory\n");
return -1;
}
// initialize the contiguous array pointed by sp with zero
for(int i = 0; i < 10; i ){
memcpy((void*)sp i, &a, sizeof(int));
}
// call the following function on different thread
threadFunc();
return 0;
}
I am getting a segmentation fault in threadFunc()
. The program prints correctly for i=0
, but gives a segmentation fault for all i > 0
. Where is it that I am going wrong?
CodePudding user response:
int main
will not compile. The minimum signature of the main
prototype is:
int main(void);
Another problem in the code shown is incorrect use of memcpy(). It does not require a loop use:
Change this:
for(int i = 0; i < 10; i ){
memcpy((void*)sp i, &a, sizeof(int));
}
to this
memset(sp, 0, 10* sizeof(int));
Finally, int the expression:
int *p;
for(int i = 0; i < 10; i ){
p = __atomic_load_n(&sp i, __ATOMIC_SEQ_CST);
printf("Value loaded = %d from %p", *p, p);
}
p
is a pointer, but it points to some location that is not yet owned by your process. Writing to it is undefined behavior, and likely the cause of your seg-fault.
CodePudding user response:
You are supposed to supply a pointer to the object here:
_atomic_load_n(&sp i, __ATOMIC_SEQ_CST);
This is not the correct thing:
&sp i
The above takes the address of sp
and adds i
, pointing ... somewhere where you have no int*
stored. Also, you want to load from an int
, not an int*
.
A fix would be:
int threadFunc() {
int p; // not an int*
for(int i = 0; i < 10; i ){
p = atomic_load_explicit(sp i, memory_order_seq_cst); // not &sp i
// or: p = __atomic_load_n(sp i, __ATOMIC_SEQ_CST);
printf("Value loaded = %d\n", p);
}
return 0;
}
(I just replaced the call with the corresponding standard call)
Also, use memset
to set what you allocated:
memset(sp, 0, sizeof(int) * 10);