简体   繁体   English

带有动态数组的 C 程序中的分段错误(核心转储)错误

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

I can't seem to figure out where this error is coming from, but I am assuming it is something to do with the allocation of the arrays/passing the arrays as parameters.我似乎无法弄清楚这个错误的来源,但我假设它与数组的分配/将数组作为参数传递有关。 Apologies, I am fairly new to C. If someone could help me figure out where this error is resulting from, it would be tremendously helpful.抱歉,我对 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;
        }
    }   

}

You've got quite a few issues here.你这里有很多问题。

First, you should initialize values like op , otherwise the comparison op != 0 is undefined.首先,您应该初始化像op这样的值,否则比较op != 0是未定义的。 Also, you pass op to scanf() instead of its address.此外,您将op传递给scanf()而不是其地址。

The immediate cause of your issue is that you're using pointers to stack variables to allocate memory using malloc .您问题的直接原因是您使用指向堆栈变量的指针来使用malloc分配内存。

In your findMin() , findMax() , findSum() , you use the int data type for the respective values, while you should be using float .在您的findMin()findMax()findSum() ,您对各自的值使用int数据类型,而您应该使用float

The edits below should start to help ( as well as turning on warnings for your compiler )下面的编辑应该开始有所帮助(以及为您的编译器打开警告

// 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

Begin by using gdb with "gdb a.out" (or the name of your compiled program)首先使用带有“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

Program received signal SIGSEGV, Segmentation fault.程序收到信号 SIGSEGV,分段错误。 0x00005555555548a8 in makeArrayCopy () makeArrayCopy () 中的 0x00005555555548a8

Then add printf("size = %d\\n", size);然后加上 printf("size = %d\\n", size); to makeArrayCopy (before the loop): 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

You will be quick to find the solution, but it will be even more valuable for you to understand how gdb work and how you can debug您将很快找到解决方案,但了解 gdb 如何工作以及如何调试对您来说更有价值

The following code cause memory corruption.以下代码会导致内存损坏。

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

The following is the reported error.以下是报告的错误。 The link to reproduce this error.重现此错误的链接

=========== Start of #0 stensal runtime message =========== ============ #0 stensal 运行时消息的开始 ============

Runtime error: [writing to the outside of a memory space] Continuing execution can cause undefined behavior, abort!运行时错误: [写入内存空间的外部]继续执行会导致未定义的行为,中止!

-
- 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]
-

============ End of #0 stensal runtime message ============ ============ #0 stensal 运行时消息结束 ============

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM