【问题标题】:Segmentation fault (core dumped) in C - While Using PTHREADSC 中的分段错误(核心转储) - 使用 PTHREADS 时
【发布时间】:2018-11-02 10:12:40
【问题描述】:

大家好, 我的代码有问题,我不知道如何解决(分段错误(核心转储))!

所以我的老师要我编写一个程序来创建 N 个踏板并让它们进行一些计算。我有 3 个全局二维数组 A、B、C(我将它们作为指针,因为我不知道大小,用户给它作为参数)。我尝试在主函数中为它们分配内存。

所以问题是当我尝试在“pthread_create(&tid[id],NULL,add,(void *)(long) i);”中创建踏板时出现分段错误:(。 我不知道为什么会这样。我尝试使用 gdb 命令,但结果是问题出在 pthread_create 中。

但是,当我输入注释时,数组(A、B、C)和它们正在使用的 malloc 正在运行(但最终结果为 0)。

我正在使用一个虚拟盒子(如果有帮助的话,里面装有 Ubuntu :D)。

以下是我目前写的代码:

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

long int p,N,Total_Sum;
long int **A,**B,**C;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_barrier_t bar;

void * add(void *arg){

    long int i,j,Local_Sum=0;
    long int lines,start,end,id;

    id = (long int)arg;
    lines = N/p;
    start = id*lines;
    end = start+lines;

    for(i=start;i<end;i++){
        for(j=0;j<N;j++){
            A[i][j] = 1;
            B[i][j] = 1;
        }
    }
    for(i=start;i<end;i++){
        for(j=0;j<N;j++){
            C[i][j] = A[i][j] * B[i][j];
            Local_Sum += C[i][j];
            printf("C[%ld][%ld] = %ld\n",i,j,C[i][j]);
        }
    }
    pthread_mutex_lock(&mutex);
    Total_Sum += Local_Sum;
    pthread_mutex_unlock(&mutex);
    pthread_barrier_wait(&bar);
    pthread_exit(0);
}

int main(int argc, char *argv[]){

    long int i,j,id;
    pthread_t *tid;
    if(argc!=3){
        printf("Provide Number Of Threads And Size\n");
        exit(1);
    }
    p = atoi(argv[1]);
    tid = (pthread_t *) malloc(p*sizeof(pthread_t));
    if(tid == NULL){
        printf("Could Not Allocate Memory\n");
        exit(1);
    }

    pthread_barrier_init(&bar,NULL,p);

    N = atoi(argv[2]);
    A = (long int**) malloc(N*sizeof(long int*));
    B = (long int**) malloc(N*sizeof(long int*));
    C = (long int**) malloc(N*sizeof(long int*));

    for(i=0;i<N;i++){
        A[i] = (long int*) malloc(N*sizeof(long int));
        B[i] = (long int*) malloc(N*sizeof(long int));
        C[i] = (long int*) malloc(N*sizeof(long int));
    }

    if((A==NULL) || (B == NULL) || (C == NULL)){
        printf("Count Not Allocate Memory\n");
        exit(1);
    }

    for(i=0;i<p;i++){
        pthread_create(&tid[id],NULL,add,(void *)(long) i);
    }
    for(i=0;i<p;i++){
        pthread_join(tid[id],NULL);
    }

    for(i=0;i<N;i++){
        free(A[i]);
        free(B[i]);
        free(C[i]);
    }
    free(A);
    free(B);
    free(C);

    printf("Final Result Is Equal To: %ld\n",Total_Sum);

    return 0;
}

******我知道由于互斥锁和障碍,它会变得有些混乱,但请向我询问更多规格:D.******

谢谢!!!!!!

【问题讨论】:

  • 编译所有警告和调试信息:gcc -Wall -Wextra -gGCC。改进您的代码以获得没有警告。 use the gdb debuggervalgrind 以了解您的程序的行为

标签: c ubuntu pthreads double-pointer pthread-barriers


【解决方案1】:

我认为唯一的问题是以下几行中的索引:

for(i=0;i<p;i++){
    pthread_create(&tid[id],NULL,add,(void *)(long) i);
}
for(i=0;i<p;i++){
    pthread_join(tid[id],NULL);
}

id 仅被声明,但从未初始化!也许这只是一个错字,您想使用i 作为tid 的索引

解决方案应该是:

for(i=0;i<p;i++){
    pthread_create(&tid[i],NULL,add,(void *)(long) i);
}
for(i=0;i<p;i++){
    pthread_join(tid[i],NULL);
}

【讨论】:

  • 哇我没看到那个o_O!!!出于某种原因,我一直在寻找更复杂的解决方案。谢谢!!!
  • @georgenikitas 没问题!我知道仅仅因为拼写错误而无法使用代码的感觉非常令人沮丧 :) 无论如何,如果这是唯一的问题,您可以接受并关闭它。
【解决方案2】:

您的核心转储问题根源的答案已经得到解决,但要解决您提出或陈述的其他问题:

第一:
关于您的陈述:我将它们作为指针,因为我不知道大小,用户将其作为参数提供

通常,在 C 语言中,您可以通过使用 VLA 来避免在代码中使用 calloc/malloc。可用于 C99 及更高版本。 (见链接)
VLA a
VLA b

第二次:
关于您的陈述:我知道这有点混乱...
它真的没有那么混乱,但您可以考虑通过将大部分工作转移到一个函数中来清理内存分配/释放步骤:

long int **A,**B,**C;
int N;
... 
//in main
N = atoi(argv[2]); 
A = Create2D(N, N);
B = Create2D(N, N);
B = Create2D(N, N);
...
free2D(A, N);
free2D(B, N);
free2D(C, N);


long ** Create2D(int c, int r)
{   
    long **arr;
    int    y = 0;

    arr   = calloc(c, sizeof(long *));
    for(y=0;y<c;y++)
    {
        arr[y] = calloc((2*y)+1, sizeof(long)); 
    }
    return arr;
}

void free2D(long **arr, int c)
{
    int i;
    if(!arr) return;
    for(i=0;i<c;i++)
    {
        if(arr[i]) 
        {
            free(arr[i]);
            arr[i] = NULL;
        }
    }
    free(arr);
    arr = NULL;
}

旁注:
你的记忆陈述并没有绝对的错误

A = (long int**) malloc(N*sizeof(long int*));  

但是,虽然 C++ 需要它,但没有理由在使用 C 时强制转换 malloccallocrealloc 的返回。 (See discussion here) 以下就足够了(在 C 中):

A = malloc(N*sizeof(long int*));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-14
    • 2017-02-25
    • 2016-07-12
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多