指针数组的分段错误

Segmentation Fault with array of pointers

对于以下代码:

#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;
}

我在 threadFunc() 中遇到分段错误。该程序正确打印了 i=0,但给出了所有 i > 0 的分段错误。我哪里出错了?

int main 

不会编译。 main原型的最小签名为:

int main(void);

所示代码中的另一个问题是 memcpy() 的使用不正确。它不需要循环使用:

改变这个:

   for(int i = 0; i < 10; i++){
        memcpy((void*)sp+i, &a, sizeof(int));
   }

至此

memset(sp, 0, 10* sizeof(int));

最后,整型表达式:

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 是一个指针,但它指向某个您的进程尚未拥有的位置。写入它是未定义的行为,可能是您的段错误的原因。

您应该在此处提供指向该对象的指针:

_atomic_load_n(&sp+i, __ATOMIC_SEQ_CST);

这不是正确的:

&sp + i

上面获取了 sp 的地址并添加了 i,指向...您没有存储 int* 的地方。此外,您想从 int 加载,而不是 int*.

解决办法是:

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

(我只是把调用换成了对应的标准调用)

此外,使用memset设置您分配的内容:

memset(sp, 0, sizeof(int) * 10);

Demo