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

如何调试含pthread的C代码并修复数组首索引垃圾值问题

问题:Pthread线程排序后主线程数组首有效元素出现垃圾值

问题描述

编写了一段基于pthread的C语言代码,功能为接收用户输入数组,拆分后通过两个线程分别执行升序归并排序(mergeSortA)、降序归并排序(mergeSortD)。线程内部输出的排序结果正常,但主线程输出时,数组的首有效索引(索引1,索引0用于存储数组长度)始终出现垃圾值,需调试修复。

原代码

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

void display(int *arr, int size) {
    int i;
    for(i=0; i<size; i++)
        printf("%d ", arr[i]);

    printf("\n");
}

void display2(int *arr, int size) {
    int i;
    for(i=1; i<size; i++)
        printf("%d ", arr[i]);
        
    printf("\n");
}


void mergeA(int* arr, int lb, int ub, int mid) {
//  printf("Inside mergeA\n");
    int i=lb, j=mid+1, k=lb;
    int newarr[1000];

    while(i<=mid && j<=ub) {
        if(arr[i] > arr[j])
            newarr[k++] = arr[j++];
        else
            newarr[k++] = arr[i++];
    }
    
    for(; i<=mid; i++)
        newarr[k++] = arr[i];
    for(; j<=ub; j++)
        newarr[k++] = arr[j];

    for(i=lb; i<=ub; i++)
        arr[i] = newarr[i];
}
void mergeD(int* arr, int lb, int ub, int mid) {
//  printf("Inside mergeD\n");
    int i=lb, j=mid+1, k=lb;
    int newarr[1000];

    while(i<=mid && j<=ub) {
        if(arr[i] < arr[j])
            newarr[k++] = arr[j++];
        else
            newarr[k++] = arr[i++];
    }
    
    for(; i<=mid; i++)
        newarr[k++] = arr[i];
    for(; j<=ub; j++)
        newarr[k++] = arr[j];

    for(i=lb; i<=ub; i++)
        arr[i] = newarr[i];
}


void mergeSortA(int* arr, int lb, int ub) {
//  printf("Inside mergeSortA\n");
    if(lb<ub) {
        int mid = (lb+ub)/2;
        mergeSortA(arr, lb, mid);
        mergeSortA(arr, mid+1, ub);
        mergeA(arr, lb, ub, mid);
    }
}

void mergeSortD(int* arr, int lb, int ub) {
//  printf("Inside mergeSortD\n");
    if(lb<ub) {
        int mid = (lb+ub)/2;
        mergeSortD(arr, lb, mid);
        mergeSortD(arr, mid+1, ub);
        mergeD(arr, lb, ub, mid);
    }
}

void* sort_a(void* args) {
    int* arr = (int*)malloc(sizeof(int)*1000);
    arr = (int*)args;
    int size = arr[0];

    printf("Inside Sort A: ");
    display2(arr, size);
    
    mergeSortA(arr, 1, size-1);
    printf("After Sort A: ");
    display2(arr, size);
    pthread_exit((void*)arr);
}

void* sort_d(void* args) {
    int* arr = (int*)malloc(sizeof(int)*1000);
    arr = (int*)args;
    int size = arr[0];

    printf("Inside Sort D: ");
    display2(arr, size);
    
    mergeSortD(arr, 1, size-1);
    printf("After Sort D: ");
    display2(arr, size);
    pthread_exit((void*)arr);
}

int main() {
    pthread_t t1, t2;
    int arr[1000];
    int i=0, j, k1=1, k2=1;

    //Taking the array as input
    while(1) {
        printf("Enter an element or 'quit' to stop input: ");
        
        char input[100];
        scanf("%s", input);

        if(strcmp(input, "quit") == 0)
            break;

        arr[i++] = atoi(input);
    }
    printf("The Array:\n");
    display(arr, i);

    //Spliting the array into two
    int arr1[1000], arr2[1000];
    for(j=0; j<i; j++) {
        if(j<i/2)
            arr1[k1++]=arr[j];
        else
            arr2[k2++]=arr[j];
    }
    //Storing size in index 0
    arr1[0] = k1;
    arr2[0] = k2;

    //Creating the threads
    pthread_create(&t1, NULL, &sort_a, (void*)arr1);
    pthread_create(&t2, NULL, &sort_d, (void*)arr2);

    //Joining the threads
    pthread_join(t1, (void*)arr1);
    pthread_join(t2, (void*)arr2);

    //After Sorting
    printf("Main Thread:\n");
    display2(arr1, k1);
    display2(arr2, k2);
}

问题根源

  1. pthread_join参数错误:pthread_join的第二个参数是void**类型,用于接收线程退出时返回的指针。原代码中pthread_join(t1, (void*)arr1); 直接将arr1的地址强转为void*,导致线程返回的指针值被写入arr1的起始位置(即索引0和索引1),破坏了原有的数组数据,这是首有效元素出现垃圾值的直接原因。
  2. 线程函数内存泄漏:线程函数中int* arr = (int*)malloc(sizeof(int)*1000); 分配内存后,立刻被传入的args指针覆盖,导致内存泄漏。

修复方案

  1. 修正pthread_join调用:由于线程直接操作主线程传入的栈数组,无需接收返回值,直接将第二个参数设为NULL即可。
  2. 移除线程函数中多余的malloc调用,直接使用传入的指针。

修复后的代码

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

void display(int *arr, int size) {
    int i;
    for(i=0; i<size; i++)
        printf("%d ", arr[i]);

    printf("\n");
}

void display2(int *arr, int size) {
    int i;
    for(i=1; i<size; i++)
        printf("%d ", arr[i]);
        
    printf("\n");
}


void mergeA(int* arr, int lb, int ub, int mid) {
    int i=lb, j=mid+1, k=lb;
    int newarr[1000];

    while(i<=mid && j<=ub) {
        if(arr[i] > arr[j])
            newarr[k++] = arr[j++];
        else
            newarr[k++] = arr[i++];
    }
    
    for(; i<=mid; i++)
        newarr[k++] = arr[i];
    for(; j<=ub; j++)
        newarr[k++] = arr[j];

    for(i=lb; i<=ub; i++)
        arr[i] = newarr[i];
}
void mergeD(int* arr, int lb, int ub, int mid) {
    int i=lb, j=mid+1, k=lb;
    int newarr[1000];

    while(i<=mid && j<=ub) {
        if(arr[i] < arr[j])
            newarr[k++] = arr[j++];
        else
            newarr[k++] = arr[i++];
    }
    
    for(; i<=mid; i++)
        newarr[k++] = arr[i];
    for(; j<=ub; j++)
        newarr[k++] = arr[j];

    for(i=lb; i<=ub; i++)
        arr[i] = newarr[i];
}


void mergeSortA(int* arr, int lb, int ub) {
    if(lb<ub) {
        int mid = (lb+ub)/2;
        mergeSortA(arr, lb, mid);
        mergeSortA(arr, mid+1, ub);
        mergeA(arr, lb, ub, mid);
    }
}

void mergeSortD(int* arr, int lb, int ub) {
    if(lb<ub) {
        int mid = (lb+ub)/2;
        mergeSortD(arr, lb, mid);
        mergeSortD(arr, mid+1, ub);
        mergeD(arr, lb, ub, mid);
    }
}

void* sort_a(void* args) {
    int* arr = (int*)args;
    int size = arr[0];

    printf("Inside Sort A: ");
    display2(arr, size);
    
    mergeSortA(arr, 1, size-1);
    printf("After Sort A: ");
    display2(arr, size);
    pthread_exit(NULL);
}

void* sort_d(void* args) {
    int* arr = (int*)args;
    int size = arr[0];

    printf("Inside Sort D: ");
    display2(arr, size);
    
    mergeSortD(arr, 1, size-1);
    printf("After Sort D: ");
    display2(arr, size);
    pthread_exit(NULL);
}

int main() {
    pthread_t t1, t2;
    int arr[1000];
    int i=0, j, k1=1, k2=1;

    //Taking the array as input
    while(1) {
        printf("Enter an element or 'quit' to stop input: ");
        
        char input[100];
        scanf("%s", input);

        if(strcmp(input, "quit") == 0)
            break;

        arr[i++] = atoi(input);
    }
    printf("The Array:\n");
    display(arr, i);

    //Spliting the array into two
    int arr1[1000], arr2[1000];
    for(j=0; j<i; j++) {
        if(j<i/2)
            arr1[k1++]=arr[j];
        else
            arr2[k2++]=arr[j];
    }
    //Storing size in index 0
    arr1[0] = k1;
    arr2[0] = k2;

    //Creating the threads
    pthread_create(&t1, NULL, &sort_a, (void*)arr1);
    pthread_create(&t2, NULL, &sort_d, (void*)arr2);

    //Joining the threads
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    //After Sorting
    printf("Main Thread:\n");
    display2(arr1, k1);
    display2(arr2, k2);
}

验证说明

修复后,线程直接修改主线程的栈数组,pthread_join不再破坏数组数据,主线程输出的数组首有效元素将和线程内部输出的一致,垃圾值问题解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 05:05:55