Home > Mobile >  Segmentation Fault with array of pointers [closed]
Segmentation Fault with array of pointers [closed]

Time:10-01

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

Demo

  • Related