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.