0

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;
}
  • 2
    [Please don't cast the return value of `malloc()` and `realloc()` in C](http://stackoverflow.com/a/605858/28169). Also, use indexing syntax: don't write `*(numbers + total_newlines)`, write `numbers[total_newlines]`. Much easier to read. – unwind Feb 10 '14 at 15:22
  • 1
    You need to allocate enough memory for your str[]. In your program, its size is not enough to store any kind of string, so that's why you get a segmentation fault. Try a value that you know will be enough to store any of the strings in your file. Just as an example: char str[255]; Also, follow the advise in the comments of your question, and try to make your code more legible. It's even hard to read as a SO question. Good luck! – ArthurChamz Feb 10 '14 at 15:28

1 Answers1

1

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.

sb9
  • 1,082
  • 7
  • 18