You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pthread_create参数传递错误:传入下标0却写入数组索引1问题排查

问题根因

该问题属于线程参数传递的经典竞态条件,核心错误是直接将循环局部变量i的地址传递给了线程函数:

  • 主线程中i是栈上的局部变量,所有创建出的线程共享同一块内存地址
  • pthread_create仅提交线程创建请求,不会等待线程启动执行就会立刻返回,主线程会继续推进循环逻辑,执行i++操作
  • 你给出的测试代码中循环仅执行1次,i初始值为0,创建线程后循环判断i < 1不再成立,退出前i会自增为1,此时线程才启动读取arg指向的值,拿到的自然是1,因此写入了patients[1]位置
修复方案

方案1:值传递(推荐用于小整数参数传递)

利用指针的存储宽度直接存放整数值,不需要传递地址,完全避免竞态:

  1. 主线程创建线程时修改传参逻辑:
pthread_create(&patients[i].thread, NULL, &registration, (void*)i)
  1. 线程函数内修改取值逻辑:
int p_num = (int)arg;

该写法符合POSIX线程标准要求,常规32/64位系统下int长度均小于等于指针长度,可安全使用

方案2:动态申请内存传参(适合传递复杂参数)

每次循环单独申请一块内存存储索引值,线程用完后释放,避免共享变量:

  1. 主线程循环内修改:
for (size_t i = 0; i < 1; i++)
{
    int* idx = malloc(sizeof(int));
    *idx = i;
    if (pthread_create(&patients[i].thread, NULL, &registration, idx) != 0)
    {
        perror("There has been an error with pthread_create().");
        free(idx);
        return 1;
    }
}
  1. 线程函数内修改:
void* registration(void* arg)
{
    int p_num = *((int*)arg);
    free(arg);
    // 剩余原有逻辑不变
}

该方案需要注意内存释放,避免出现内存泄漏

内容的提问来源于stack exchange,提问作者covenant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 22:45:08