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

pthread_join返回值异常 多线程拆分求数组最小值结果错误

多线程拆分数组求全局最小值 问题修复

核心错误点

  • 线程返回局部变量地址:Find_min_val中返回栈上局部变量temp的地址,线程退出后栈空间会被系统回收,后续访问该地址属于未定义行为,读取到的值完全不可控。
  • 子数组长度计算错误:指针无法通过sizeof计算指向数组的长度,64位环境下该计算结果恒为2,和实际子数组长度没有任何关系。
  • 奇偶判断逻辑错误:if(k=0)是赋值操作而非相等判断,且偶数分支的halfArgc2=halfArgc2属于无效赋值。
  • 子数组拷贝范围错误:第二个子数组的拷贝起始地址多减了1,导致两个子数组元素重叠,拆分逻辑完全错误。
  • 结果存储下标错误:两个线程的返回值都存入Min_Val[1],第一个线程的计算结果直接被覆盖。
  • 未初始化变量访问:定义arr后直接读取arr[0]给min赋值,此时arr还未填充数据,属于非法访问。

修复方案

自定义结构体传递子数组的起始地址和长度,返回值改用堆内存存储避免栈回收问题,同时修正拆分逻辑和结果存储逻辑:

修复后完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

// 自定义结构体传递线程参数:数组起始地址+长度
typedef struct {
    int *arr;
    int len;
} ThreadArg;

int min_value(int a[], int n) {
    int c, index = 0;
    for (c = 1; c < n; c++)
        if (a[c] < a[index])
            index = c;
    return a[index];
}

void* Find_min_val(void* arg) {       
    ThreadArg *s = (ThreadArg*) arg;
    int numOfarray = s->len;
    // 打印子数组元素
    for(int j=0; j<numOfarray; ++j) {
        printf("%d\n", s->arr[j]);
    }
    // 计算子数组最小值
    int temp = min_value(s->arr, numOfarray);
    printf("Sub Min = %d\n", temp);
    // 用堆内存存储返回值,避免栈空间回收问题
    int *ret = malloc(sizeof(int));
    *ret = temp;
    return ret;
}

int main(int argc, char const *argv[]) {
    int j, element;
    int halfArgc1, halfArgc2, k = (argc-1) % 2;
    pthread_t tid1, tid2;

    if(argc <= 1) {
        fprintf(stderr, "Not enough arguments entered\n");
        return 1;
    }
    // 填充输入数组
    int arr[argc-1];
    for(j=1; j<argc; j++) {
        element = atoi(argv[j]);
        arr[j-1] = element;
    }
    // 拆分数组
    halfArgc1 = (argc - 1) / 2;
    if(k == 0) {
        halfArgc2 = halfArgc1;
    } else {
        halfArgc2 = halfArgc1 + 1;
    }
    int subArr1[halfArgc1], subArr2[halfArgc2];
    memcpy(subArr1, arr, halfArgc1 * sizeof(int));
    memcpy(subArr2, arr + halfArgc1, halfArgc2 * sizeof(int));
    // 构造线程参数
    ThreadArg arg1 = {.arr = subArr1, .len = halfArgc1};
    ThreadArg arg2 = {.arr = subArr2, .len = halfArgc2};

    if (pthread_create(&tid1, NULL, Find_min_val, (void*)&arg1))
        return 1;
    if (pthread_create(&tid2, NULL, Find_min_val, (void*)&arg2))
        return 1;
    
    int* r;
    int Min_Val[2];
    if (pthread_join(tid1, (void**) &r)) {
        fprintf(stderr, "Could not join Thread 1\n");
        return 1;
    }
    Min_Val[0] = *r;
    free(r); // 释放线程返回的堆内存
    if (pthread_join(tid2, (void**) &r)) {
        fprintf(stderr, "Could not join Thread 2\n");
        return 1;
    }
    Min_Val[1] = *r;
    free(r);

    printf("Global Min = [%d]\n", min_value(Min_Val, 2));
    return 0;
}

运行验证

执行命令:

gcc -pthread -o hw3 hw3.c
./hw3 1 2 3 4 5

输出结果:

1
2
Sub Min = 1
3
4
5
Sub Min = 3
Global Min = [1]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 09:06:03