سؤال

The address of number changes to a high value then gives me a seg-fault. I'm dumbfounded why this is, since I don't ever do any pointer-math up to the while-fgets statement. The program is supposed to go through three files of unsorted integers and place them in one array. The array is then bubble sorted then output to some other text file. It is for a computer science class. I thought i prepared well for this class by reading Franek's c memory book, but I can't explain why the array's address randomly changed after I created the fgets statement.

Here is my code:

#include <stdio.h>
#include <stdlib.h>
#define DEBUG 1
#define TRUE 1
#define FALSE 0
#define INCREMENT_MEM 128
#define MAX_LENGTH 8
#define INIT_SIZE 8
#define NUMBER_OF_TEXT_FILES 3

int* resize(int*, int*);
void myswap(int *, int*);

int main(){
FILE *fp;
int init_size = INIT_SIZE;
int *maxsize = &init_size;
int total_newlines = -1;
int* numbers;
char str[] = "";
char file[] = "list0.txt";
int array_is_ordered = TRUE;
int i, j;
    numbers = (int*) malloc (INIT_SIZE * sizeof(int) );
    for(i = 0; i < NUMBER_OF_TEXT_FILES; i++){
        file[4] = (char)((int)'0' + i);
        fp = fopen(file , "r" );
        while( fgets( str, MAX_LENGTH, fp ) != NULL){
        total_newlines++;
            if(total_newlines>= *maxsize){
                numbers = resize(numbers, maxsize);
            }
                                                                    #if DEBUG == 1
                                                                    printf("total_newlines=%d str=%s numbers=%d *number=%d",total_newlines, str, (int)numbers, *numbers );
                                                                    #endif
            *(numbers + total_newlines) = atoi(str);

        }
    fclose(fp);
    }

    int temp_int = total_newlines - INCREMENT_MEM;
    numbers = resize(numbers, &temp_int);
    total_newlines = temp_int;

    /*
    BUBBLE SORT!!!!!!!!!!!!! LULZ
    */
    do{ 
        for(i = 1; i < total_newlines; i++){
            array_is_ordered = TRUE;
            if( *(numbers+i-1) > *(numbers+i)){
                array_is_ordered = FALSE;
                myswap( &(*(numbers+i-1)) , &(*(numbers+i)) );
            }
        }
    } while(array_is_ordered==FALSE);

    /*write output code using fprintf. don't forget to close all files and free all standing memory.*/

    FILE *of;
    of = fopen("output.txt", "w");
    printf("Opening output file for sorted digits\n");
    for(i = 0 ; i < total_newlines ; i++){
        fprintf(of, "%d\n", *(numbers+i));
        printf("%d\n", *(numbers+1) );
    }

    fclose(of);
    fclose(fp);
    free(numbers);

return 0;
}

void myswap(int *a, int *b){
int temp = *a;
    *a = *b;
    *b = temp; 
}
int* resize(int* array , int* size){
int *temp;
    *size = *size + INCREMENT_MEM;
    temp = (int *) realloc ( array, (*size) * sizeof(int) );
    if(temp!=NULL){
        array = temp;
    }else{
        printf("Resize to %d did not work", *size);
        exit(0);
    }
return array;
}
هل كانت مفيدة؟

المحلول

change

char str[] = "";

to

char str[MAX_LENGTH+2];

or similar. Your code reads into the buffer str, but str has no memory allocated. So fgets overwrites some data on the stack, including your numbers pointer.

+2 because I assumed that your numbers are up to _MAX_LENGTH_ long and there should additionally be enough space for \n and zero terminator.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top