指针数组的分段错误
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);
对于以下代码:
#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);