简体   繁体   中英

Reading file to char** using fgets and memcpy

I'm trying to read a set of lines from a file to an array. I'm doing this to learn malloc and realloc.

#define MAX_LINE 301

char** read_file_lines(char* filename) {
    char** ptr = NULL;
    int max = 5;
    int i = 0;
    FILE *fp = fopen(filename, "r");

    if(fp != NULL) {
        char line[MAX_LINE];
        while(fgets(line, MAX_LINE, fp) != NULL) {

            /* allocate some extra memory for some more lines */
            if(i == max) {
                int new_max = max * 2;
                int nr_bytes = new_max * sizeof(char) * MAX_LINE;
                char **ptr2 = realloc(ptr, nr_bytes);
                if(ptr2 != NULL) {
                    ptr = ptr2;
                    ptr2 = NULL;
                    max = new_max;
                }
            }

            // ptr[i] = line;
            // strcpy(ptr[i], line);
            memcpy(ptr[i], line, strlen(line));
            i++;
        }
        fclose(fp);
    }
    else {
        printf("Error opening file %s\n", filename);
    }

    return ptr;
}

The code compiles. However, when it is executed, an error occurs (the program crashes).

I did some debugging and determined that the problem is in up in the memcpy () instruction. I had previously tried using strcpy , which also gives a similar problem.

I went to check memcpy ()'s protocolo and it is as followS:

void * memcpy ( void * destination, const void * source, size_t num );

Now, if ptr is char** , isn't ptr[i] equivalent to a char* ?

Thanks for your comments.

It looks like ptr isn't initialized to point to any memory at all. Also, you're not allocating any memory for the individual lines.

To initialize ptr , change the declaration to:

int max = 5;
char** ptr = malloc(max * sizeof(char*));

Try adding this before the call to memcpy:

        ptr[i] = malloc(strlen(line) + 1);

and change the calculation for the realloc call:

            int nr_bytes = new_max * sizeof(char*);

EDIT: To explain in more detail: ptr is a pointer to an array of pointers. You have to allocate memory for ptr (that is, enough memory just to store individual pointers). In addition to this , you also have to allocate each individual array of characters that the individual elements of ptr will point to.

The first change I suggested ensures that ptr always points to enough memory to hold 5 pointers (or more, once it's been realloc'd.)

The second change ensures that each member of ptr always points to valid memory before you try to access it as a pointer.

And the third change is required because ptr points to elements that are pointers to char , not char .

问题是,在第一执行存储器未分配: i是0, max是5, if条件为假并且realloc永远不会执行。

Nah. Arrays are not pointers. Pointers to pointers are not arrays of arrays. If you want a two-dimensional dynamic array, then you have to allocate memory for 1. the array of pointers that point to the individual lines, and 2. for the lines themselves too.

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