简体   繁体   中英

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.

#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. Also, you pass op to scanf() instead of its address.

The immediate cause of your issue is that you're using pointers to stack variables to allocate memory using malloc .

In your findMin() , findMax() , findSum() , you use the int data type for the respective values, while you should be using 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) 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. 0x00005555555548a8 in makeArrayCopy ()

Then add printf("size = %d\\n", size); to makeArrayCopy (before the loop):

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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