为啥我在这个 c 代码上遇到分段错误?

Posted

技术标签:

【中文标题】为啥我在这个 c 代码上遇到分段错误?【英文标题】:Why am I getting a segmentation fault on this c code?为什么我在这个 c 代码上遇到分段错误? 【发布时间】:2020-12-03 01:30:40 【问题描述】:
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <string.h>


void createProcess(pid_t p, char* args[])

    p = fork();
    if (p == 0)
    
        execvp("./u", args);
    


void swap(float lat[], float lng[], float mag[], int j)

    float temp;
    
    temp = lat[j];
    lat[j] = lat[j+1];
    lat[j+1] = temp;

    temp = lng[j];
    lng[j] = lng[j+1];
    lng[j+1] = temp;

    temp = mag[j];
    mag[j] = mag[j+1];
    mag[j+1] = temp;


void bubbleSort(float lat[], float lng[], float mag[], int n)

    for (int i = 0; i < n - 1; i++)
    
        for (int j = 0; j < n-i-1; j++)
        
            if (lat[j] > lat[j+1])
            
                swap(lat, lng, mag, j);
            
        
    


int main(void)

    time_t t;
    char s[256];
    int i, j, status;
    pid_t p, p2, p3, p4, p5, p6, p7, p8, p9, p10, wpid;
    int MAX_PROCESSES = 10;
    char* files[MAX_PROCESSES];
    status = 0;

    time_t a = time(NULL);

    /* ============================================== */
    // INSERTING INFORMATION INTO ARRAYS

    char *fileName = "earthquake_30days.txt";
    char line[256];
    int fileSize = -1;

    FILE *fp = fopen(fileName, "r");

    while(fgets(line, sizeof(line), fp))
    
        fileSize++;
    
    
    
    printf("The total number of entries in %s is %d\n", fileName, fileSize);

    fclose(fp);

    fp = fopen(fileName, "r");

    float latitude[fileSize];
    float longitude[fileSize];
    float magnitude[fileSize];
    
    char *token;
    
    i = -1;

    while (fgets(line, sizeof(line), fp))
    
        if (i != -1)
        
            token = strtok(line, ",");
            token = strtok(NULL, ",");
            latitude[i] = atof(token);
            token = strtok(NULL, ",");
            longitude[i] = atof(token);
            token = strtok(NULL, ",");
            magnitude[i] = atof(token);
        
        i++;
    
    
    fclose(fp);
    
    // Inserting info into file

    int processes;
    printf("\nEnter number of concurrent processes: ");
    scanf("%d", &processes);
    printf("\n");
    
    if (processes > MAX_PROCESSES)
    
        printf("That is too much.\n");
        exit(0);
    

    clock_t begin;

    if (processes != 1)
    
        int pieceSize = fileSize/processes;
        char* files[processes];
        int first, last;
        first = 0;
        last = pieceSize;

        for (i = 0; i < processes; i++)
        
            strcpy(line, "piece");
            sprintf(s, "%d", i);
            strcat(line, s);
            strcat(line, ".txt");
            fileName = line;
            files[i] = fileName;

            fp = fopen(fileName, "w");

            // INSERTING INFORMATION TO FILES
            for (j = first; j < last; j++) 
                // CREATING INFORMATION
                sprintf(s, "%f", latitude[j]);
                strcpy(line, s);
                strcat(line, ",");
                sprintf(s, "%f", longitude[j]);
                strcat(line, s);
                strcat(line, ",");
                sprintf(s, "%f", magnitude[j]);
                strcat(line, s);
                fprintf(fp, "%s\n", line);
            
            fclose(fp);
            first += pieceSize;
            if (i == processes - 2) 
                last += pieceSize;
                j = fileSize - last;
                last += j;
             else 
                last += pieceSize;
            
        
    
        
        char* args[MAX_PROCESSES] = "piece0.txt", NULL,
                        "piece1.txt", NULL,
                        "piece2.txt", NULL,
                        "piece3.txt", NULL,
                        "piece4.txt", NULL,
                        "piece5.txt", NULL,
                        "piece6.txt", NULL,
                        "piece7.txt", NULL,
                        "piece8.txt", NULL,
                        "piece9.txt", NULL;

        createProcess(p, args[0]);
        createProcess(p2, args[1]);
        
        if (processes >= 3)
            createProcess(p3, args[2]);
        
        if (processes >= 4)
            createProcess(p4, args[3]);
        
        if (processes >= 5)
            createProcess(p5, args[4]);
        
        if (processes >= 6)
            createProcess(p6, args[5]);
        
        if (processes >= 7)
            createProcess(p7, args[6]);
        
        if (processes >= 8)
            createProcess(p8, args[7]);
        
        if (processes >= 9)
            createProcess(p9, args[8]);
        
        if (processes >= 10)
            createProcess(p10, args[9]);
        

        while ((wpid = wait(&status)) > 0);
     else 
        begin = clock();

        // Sorting from arrays

        bubbleSort(latitude, longitude, magnitude, fileSize);

        clock_t end = clock();

        double total_time = (double)(end-begin)/CLOCKS_PER_SEC;
        printf("Total time to sort %s was %0.3fs\n", fileName, total_time);
    

    time_t b = time(NULL);

    printf("\nTotal time of program was %lds\n", (b-a));

    exit(0);

为什么我在此代码中收到“分段错误:11”错误?是不是因为 MAX_PROCESSES 没有初始化?

我还收到了该行的“可变大小对象可能未初始化”错误 "char* args[MAX_PROCESSES] = "piece0.txt", NULL,"

我不知道我的代码哪里错了,所以如果有人可以查看它并指出我正确的方向,那就太棒了。

【问题讨论】:

尝试通过 valgrind 运行您的代码。如果你的内存管理不善,它会告诉你在哪里。 请不要添加无关的语言标签。 您有两个 files 数组:files[MAX_PROCESSES]files[processes]。你永远不会使用第一个数组。您分配给第二个数组,但从不将其用于任何事情。 为什么你会收到所有sprintf()strcat() 的电话?只需使用fprintf(fp, "%f,%f,%f\n", latitude[j], longitude[j], magnitude[j]); 【参考方案1】:

char *args[MAX_PROCESSES] 表示字符串数组。但是您正在使用二维字符串数组对其进行初始化。所以应该是:

char* args[2][] = 
    "piece0.txt", NULL,
    "piece1.txt", NULL,
    "piece2.txt", NULL,
    "piece3.txt", NULL,
    "piece4.txt", NULL,
    "piece5.txt", NULL,
    "piece6.txt", NULL,
    "piece7.txt", NULL,
    "piece8.txt", NULL,
    "piece9.txt", NULL
;

【讨论】:

仍然收到错误“ 171:14:错误:可变大小的对象可能未初始化 char* args[2][MAX_PROCESSES] = " 使 MAX_PROCESSES 成为宏而不是变量。或者只使用[]

以上是关于为啥我在这个 c 代码上遇到分段错误?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在这个迭代器中遇到分段错误?

为啥在此 C++ 代码中出现分段错误?

为啥调用 glCreateShader 时这个 OpenGL 着色器分段错误?

为啥我在 C 中收到警告“分段错误,核心转储”

请解释为啥这个 C 代码给我一个分段错误?

为啥在某些机器上堆栈溢出,但在另一台机器上出现分段错误?