【问题标题】:Segmentation Fault with array of pointers带有指针数组的分段错误
【发布时间】:2021-11-22 08:32:22
【问题描述】:

对于以下代码:

#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 &gt; 0 给出了分段错误。我哪里错了?

【问题讨论】:

  • 您不需要强制转换为 void*。 (并且您的程序中没有指针数组)
  • int main{ 看起来很奇怪——你使用的是什么编译器?如果这应该是标准 C,请在发布之前测试以编译您的代码。
  • @RestingPlatypus:不,你没有。
  • 请把代码放上来,你可以自己编译。如果这确实为您编译,请说明您正在使用什么编译器(和选项)。
  • &amp;sp+i 不是你想要的。它获取sp 的地址并将i 添加到其中。但是在单个指针之后没有其他指针。

标签: c pointers segmentation-fault


【解决方案1】:

你应该在这里提供一个指向对象的指针:

_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

【讨论】:

  • 非常感谢!我尝试了类似的方法,但我设置了类似int **p,然后是p = &amp;sp,然后将&amp;sp+i替换为p[i],但这不起作用。
  • @RestingPlatypus 不客气。我猜你可能错误地添加了指针,以至于它最终指向越界。所有** 都让它变得棘手。
【解决方案2】:
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表达式:

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

【讨论】:

    猜你喜欢
    • 2022-11-11
    • 2013-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-26
    相关资源
    最近更新 更多