linux 如何修复此分段错误?

hjzp0vay  于 2022-11-22  发布在  Linux
关注(0)|答案(1)|浏览(144)

我正在尝试运行一个我编写的程序,该程序用于将N × N矩阵相乘。但是,我遇到了分段错误。我有一个没有线程的程序代码。但是,我无法将我的代码用于多线程。我正在尝试在raspberry pi 4上运行该代码。调试器指出,在下面的行中,我收到了错误信号SIGSEGV:args.A[i][j] = rand() % 100;
我试过在我分配内存的代码段周围放置printf语句,但是它们从来没有运行过,所以我假设seg错误在任何代码实际运行之前发生。我在互联网上做了一些关于解决seg错误的研究,那是当我尝试使用调试器时,但是我不明白为什么它在设置矩阵元素时会有问题。特别是因为我以前的无线程程序有同样的代码行,并且运行时没有任何错误。如果有反馈,将非常感谢。下面是我的代码:

/* Program must be passed exactly one integer that satisfies the following condition:
 * N % n = 0, where N is the square matrices' dimensions and n is the number of threads.
 */

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

#define N 2000

typedef struct __myarg_t
{
    FILE *Aptr, *Bptr, *Cptr;   // Files containing the matrices
    int **A, **B, **C, **T;     // Matrices A , B, resultant and transpose of B
    int rows;           // Number of rows each thread computes
    int cur;            // Current thread number
} myarg_t;

void *mythread(void *arg)
{
    myarg_t *m  = (myarg_t *) arg;
    int start = m->cur++ * m->rows;
    int end = start + m->rows;

    // Matrix Multiplication for rows start:(end - 1)
    for (int i = start; i < end; i++)
    {
        for (int j = start; j < end; j++) 
        {
            int num = 0;

            for (int k = 0; k < N; k++)
            {
                num += m->A[i][k] * m->T[j][k];
            }

            m->C[i][j] = num;
        }
    }

    return NULL;
}

int main(int argc, char *argv[])
{
    if (argc != 2)
        {
        fprintf(stderr, "usage: main-first <#ofthreads>\n");
        exit(1);
    }

    pthread_t *thread;
    clock_t tic, toc;
    myarg_t args;
    int rc, n;

    args.cur = 0;
    args.rows = N/n;
    n = atoi(argv[1]);
    args.Aptr = fopen("A_multi.txt", "w");
    args.Bptr = fopen("B_multi.txt", "w");
    args.Cptr = fopen("C_multi.txt", "w");
    args.A = (int**)malloc(N * sizeof(int*));
    args.B = (int**)malloc(N * sizeof(int*));
    args.C = (int**)malloc(N * sizeof(int*));
    args.T = (int**)malloc(N * sizeof(int*));
    thread = (pthread_t *)malloc(n * sizeof(pthread_t));

    // Dynamically allocate memory for 2D Array
    for (int i = 0; i < N; i++)
        {
        args.A[i] = (int*)malloc(N * sizeof(int*));
        args.B[i] = (int*)malloc(N * sizeof(int*));
        args.C[i] = (int*)malloc(N * sizeof(int*));
        args.T[i] = (int*)malloc(N * sizeof(int*));
    }

    // Assign values to the elements of the Matrices
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; i++)
        {
            args.A[i][j] = rand() % 100;
            args.B[i][j] = rand() % 100;
            args.T[j][i] = args.B[i][j];
        }
    }

    tic = clock();

    // Create threads
    for (int i = 0; i < n; i++) 
    {
        rc = pthread_create(&thread[i], NULL, mythread, &args);
        
        if (rc != 0)
        {
            printf("pthread_create failed with thread %d.\n", i);
            exit(1);
        }
    }

    // Wait for threads to complete
    for (int i = 0; i < n; i++) 
    {
        rc = pthread_join(thread[i], NULL);                                                                              
        if (rc != 0)
        {
            printf("ptphread_join failed with thread %d.\n", i);
            exit(1);
        }
    }

    toc = clock();
    
    printf("Elapsed: %f seconds\n", (double)(toc - tic) / CLOCKS_PER_SEC);

    // Write matrices to their output files
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
        {
            fprintf(args.Aptr, "%d ", args.A[i][j]);
            fprintf(args.Bptr, "%d ", args.B[i][j]);
            fprintf(args.Cptr, "%d ", args.C[i][j]);
        }

        fprintf(args.Aptr, "\n");
        fprintf(args.Bptr, "\n");
        fprintf(args.Cptr, "\n");
    }

    // Deallocate memory
    for (int i = 0; i < N; i++)
    {
        free(args.A[i]);
        free(args.B[i]);
        free(args.C[i]);
        free(args.T[i]);
    }

    free(args.A);
    free(args.B);
    free(args.C);
    free(args.T);
    fclose(args.Aptr);
    fclose(args.Bptr);
    fclose(args.Cptr);

    return 0;

}
yx2lnoni

yx2lnoni1#

1.变更:

int rc, n;
    ...
    args.rows = N/n;
    n = atoi(argv[1]);

至:

int rc;
    ...
    int n = atoi(argv[1]);
    if(!n) {
      // atoi() will return for "0" or error
    }
    args.rows = N/n;

1.“赋值”注解后的第二个循环可能增加了错误的变量i,但应该是j。否则i将是2 * (N-1),这将溢出数组ABT,这些数组包含N元素。这将导致segfault。

相关问题