Plexxis
Plexxis

Reputation: 27

Resizing 2D char array causes exception

I'm new to C, so please forgive me for noobie mistakes, we all need to start somewhere.

My task is to get some lines from a big file and store each line in a 2d array, where li[0] is the first line and so on...

On top of that, I have no ideia whats the size of this 'big text', so I came up with the code bellow to resize the array every time it reaches critical size (is there an easier way to do that?). Also, I could not find a better way to define the line size other than setting it very high.

The code bellow fails on the second time it resizes with an exception on this line char **temp = realloc(lin, LINE_QUANT * sizeof(char*));

Whats causing that exception?


#include <stdio.h>
#include <stdlib.h>
#define LINE_TAM 200

size_t PAL_QUANT = 100, LINE_QUANT = 3;

int main(){
    int i = 0;
    char **li = (char**) malloc(LINE_QUANT * sizeof(char*));
    char fname[30];
    FILE *arq = NULL;

    // alloc word container
    for (i=0; i < LINE_QUANT; i++)
        li[i] = malloc(LINE_TAM * sizeof(char));

    if(li == NULL) return 0;

    //(ommited file opener)

    i = 0;

    //getting words from file (unknown size)
    while(fgets(li[i], LINE_TAM, arq) != NULL){
        while(i >= LINE_QUANT - 1) resizeArr(li);
        i++;
    }


return 1;
}

void resizeArr(char **lin){
    int i;
    LINE_QUANT = LINE_QUANT * 2;
    char **temp = realloc(lin, LINE_QUANT * sizeof(char*));
    if(temp) {
        lin = temp;
        for (i = LINE_QUANT/2; i < LINE_QUANT; i++){
            lin[i] = malloc(LINE_TAM * sizeof(char*));
            if (lin[i] == NULL)
                exit(1);
        }
    }
    else
        exit(1);

    free(temp);
}

Upvotes: 1

Views: 48

Answers (1)

user3121023
user3121023

Reputation: 8286

Since each element of the array will be the same size, use could be made of a pointer to array, (*li)[LINE_TAM].
Because resizeArr modifies the pointer, either a pointer to the pointer needs to be passed to the function or the function needs to return the pointer.
realloc will take care of any required free, so do not free the pointers.
This uses stdin but it can be modified to use a FILE*.
Enter stop to exit the loop.

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

#define LINE_TAM 200

void resizeArr ( size_t *line_quant, char (**lin)[LINE_TAM]);

int main(){
    int i = 0;
    char (*li)[LINE_TAM] = NULL;//pointer to array
    size_t Line_Quant = 3;

    // alloc word container
    if ( NULL == ( li = malloc( sizeof *li * Line_Quant))) {
        fprintf ( stderr, "malloc problem\n");
        return 1;
    }

    i = 0;

    //getting words from file (unknown size)
    while ( fgets ( li[i], LINE_TAM, stdin) != NULL) {
        if ( 0 == strcmp ( li[i], "stop\n")) {
            break;
        }
        if (i >= Line_Quant - 1) {
            resizeArr ( &Line_Quant, &li);
        }
        i++;
    }

    free ( li);

    return 1;
}

void resizeArr ( size_t *line_quant, char (**lin)[LINE_TAM]) {
    int i;
    char (*temp)[LINE_TAM] = realloc ( *lin, sizeof **lin * *line_quant * 2);
    if ( temp) {//success
        *lin = temp;//assign back to caller
        *line_quant *= 2;//increase by two
        for ( i = *line_quant / 2; i < *line_quant; i++) {
            (*lin)[i][0] = 0;
        }
    }
    else {
        fprintf ( stderr, "realloc problem\n");
    }
}

Upvotes: 1

Related Questions