簡體   English   中英

帶有動態數組的 C 程序中的分段錯誤(核心轉儲)錯誤

[英]Segmentation fault (core dumped) Error in C program with dynamic arrays

我似乎無法弄清楚這個錯誤的來源,但我假設它與數組的分配/將數組作為參數傳遞有關。 抱歉,我對 C 還很陌生。如果有人能幫我找出這個錯誤的原因,那將是非常有幫助的。

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


void getSize(int *sizePtr) {
    printf("Please enter the size of the class: ");
    scanf("%i", sizePtr);
}

void allocateMemory(float *scoresPtr, int size) {
    scoresPtr = malloc(size * (sizeof(float)));
}

void readScores(float *scores, int size) {
    int i;
    printf("Enter each score as a floating point value, each on a separate line, followed by enter: \n");
    for (i = 0; i < size; i++) {
        scanf("%f", &scores[i]);
    }
}

void makeArrayCopy(float *original, float *copy, int size) {
    int j;
    for (j = 0; j < size; j++) {
        copy[j] = original[j];
    }
}

void findMin(float *scores, int size) {
    int min = scores[0];
    int i;

    for (i = 1; i < size; i++) {
        if (scores[i] < min) {
            min = scores[i];
        }
    }
    printf("%.1f", min);
}

void findMax(float *scores, int size) {
    int max = scores[0];
    int i;

    for (i = 1; i < size; i++) {
        if (scores[i] > max) {
            max = scores[i];
        }
    }
    printf("%.1f", max);
}


void findSum(float *scores, int size) {
    int i;
    int sum = 0;

    for (i = 0; i < size; i++) {
        sum += scores[i];
    }

    printf("%.1f", sum);
}

void findMean(float *scores, int size) {
    int i;
    double mean = 0;

    for (i = 0; i < size; i++) {
        mean += scores[i];
    }

    mean /= size;
    mean = (float)mean;
    printf("%.1f", mean);
}

void findMedian(float *sortedScores, int size) {
    int mod = size % 2;
    int sizeDivTwo = size / 2;
    float median;

    if (mod = 0) {
        median = (sortedScores[sizeDivTwo] + sortedScores[sizeDivTwo + 1]) / 2;
    } else {
        median = sortedScores[sizeDivTwo + 1];
    }
    printf("%.1f", median);
}

void printAllScores(float *scores, int size) {
    int i;
    printf("%s", "Class Scores: \n");

    for (i = 0; i < size; i++) {
        printf("%.1f", scores[i]);
        printf("%c", "\n");
    }
}

void sortAscending(float *scores, int size) {
    int i, j;
    float temp;

    for (i = 0; i < size;  i++) {
        for (j = 0;  j < size - 1; j++) {
            if (scores[j] > scores[j + 1]) {
                temp = scores[j];
                scores[j] = scores[j+1];
                scores[j + 1] = temp;
            }
        }
    }
}




int main() {
    float scores;
    int size;
    float sortedCopy;
    int op;

    getSize(&size);
    allocateMemory(&scores, size);
    readScores(&scores, size);

    allocateMemory(&sortedCopy, size);
    makeArrayCopy(&scores, &sortedCopy, size);
    sortAscending(&sortedCopy, size);


    while (op != 0) {
        printf("%s", "Please choose an option: \n 1: Calculate sum \n 2: Calculate mean \n 3: Calculate median \n 4: Find minimum score \n 5: Find maximum score \n 6: Print all scores \n 7: Print all scores in ascending order \n8: Exit");
        scanf("%i", op);

        switch(op) {
            case 1:
                findSum(&scores, size);
                break;
            case 2:
                findMean(&scores, size);
                break;
            case 3: 
                findMedian(&sortedCopy, size);
                break;
            case 4: 
                findMin(&scores, size)
                break;
            case 5: 
                findMax(&scores, size);
                break;
            case 6:
                printAllScores(&scores, size);
                break;
            case 7:
                printAllScores(&sortedCopy, size);
                break;
            case 8:
                op = 0;
                break;
        }
    }   

}

你這里有很多問題。

首先,您應該初始化像op這樣的值,否則比較op != 0是未定義的。 此外,您將op傳遞給scanf()而不是其地址。

您問題的直接原因是您使用指向堆棧變量的指針來使用malloc分配內存。

在您的findMin()findMax()findSum() ,您對各自的值使用int數據類型,而您應該使用float

下面的編輯應該開始有所幫助(以及為您的編譯器打開警告

// in main() 
float *scores;
float *sortedCopy;
int   op = -1;

// remove & from before scores and sorted copy in all other function calls
allocateMemory(&scores, size);
allocateMemory(&sortedCopy, size);

// in the while loop
scanf("%d", &op);

// at the end of main(), don't forget to free mem
free(scores);
free(sortedCopy);

// in allocateMemory
void allocateMemory(float **scoresPtr, int size) { 
    *scoresPtr = malloc(size * (sizeof(float))); 
}

// in findMedian()

if (mod == 0) { // == is for comparison, = is for assignment

首先使用帶有“gdb a.out”(或已編譯程序的名稱)的 gdb

(gdb) start
Temporary breakpoint 1 at 0xd0f
Starting program: a.out 

Temporary breakpoint 1, 0x0000555555554d0f in main ()
(gdb) next
Single stepping until exit from function main,
which has no line number information.
Please enter the size of the class: 5
Enter each score as a floating point value, each on a 
separate line, followed by enter: 
4.5
4.7
4.7
4.6
4.8

程序收到信號 SIGSEGV,分段錯誤。 makeArrayCopy () 中的 0x00005555555548a8

然后加上 printf("size = %d\\n", size); makeArrayCopy(在循環之前):

Please enter the size of the class: 3
Enter each score as a floating point value, each on a 
separate line, followed by enter: 
2.5
2.6
2.7
size = 1076258406

您將很快找到解決方案,但了解 gdb 如何工作以及如何調試對您來說更有價值

以下代碼會導致內存損壞。

...
scanf("%f", &scores[i]); // line 18, write to the outside of scores. 
...
float scores; // line 116
...

以下是報告的錯誤。 重現此錯誤的鏈接

============ #0 stensal 運行時消息的開始 ============

運行時錯誤: [寫入內存空間的外部]繼續執行會導致未定義的行為,中止!

-
- Writing 4 bytes to 0xffc067d0 will clobber the adjacent data.
-
- The memory-space-to-be-written (start:0xffc067cc, size:4 bytes) is bound to 'scores' at
-     file:/prog.c::116, 9
-
-  0xffc067cc               0xffc067cf
-  +------------------------------+
-  |the memory-space-to-be-written|......
-  +------------------------------+
-                                  ^~~~~~~~~~
-        the write starts at 0xffc067d0 that is right after the memory-space end.
-
- Stack trace (most recent call first) of the write.
- [0]  file:/musl-1.1.10/src/stdio/vfscanf.c::302, 5
- [1]  file:/musl-1.1.10/src/stdio/vscanf.c::7, 9
- [2]  file:/musl-1.1.10/src/stdio/scanf.c::25, 8
- [3]  file:/prog.c::18, 5
- [4]  file:/prog.c::123, 3
- [5]  [libc-start-main]
-

============ #0 stensal 運行時消息結束 ============

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM