C: Realloc 的行为方式我不明白为什么
C: Realloc behaves in a way i cant figure out why
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[]){
char buffer[103];
char **words = malloc(1 * sizeof(*words));
size_t counter = 0;
size_t array_size = 2;
for(int i = 0; i < 5; i++){
if(!fgets(buffer, 103, stdin)){
fputs("fgets failed", stderr);
}
words[counter] = buffer;
char **more_words = realloc(words, array_size * sizeof(*more_words));
words = more_words;
array_size++;
counter ++;
}
printf("********************************************************");
for(int i = 0; i < 5; i++){
printf("%s\n", words[i]);
}
}
现在这是我正在处理的简化代码。
我知道我不会处理很多可能发生的错误。
重点是,当您执行此操作时,单词数组似乎有 'last' 条目中的 5 个条目。
假设你给 fgets :
1
2
3
4
5
,然后
words[0] = 5;
words[1] = 5;
words[2] = 5;
words[3] = 5;
words[4] = 5;
为什么不是:
words[0] = 1;
words[1] = 2;
words[2] = 3;
words[3] = 4;
words[4] = 5;
?
if(!fgets(buffer, 103, stdin)){
fputs("fgets failed", stderr);
}
words[counter] = buffer;
您有一个缓冲区,每次调用 fgets
时都会被覆盖,因此 words
中的所有字符串实际上都指向同一个字符数组。试试这个:
if(!fgets(buffer, 103, stdin)){
fputs("fgets failed", stderr);
}
// here make a new buffer and copy the string just read into it.
char *new_buffer = malloc(strlen(buffer) + 1);
strcpy(new_buffer, buffer);
words[counter] = new_buffer;
问题不在于 realloc
,而是你分配给你分配的指针的内容:
words[counter] = buffer;
buffer
始终是同一个指针,所以最后一个字符串读入缓冲区。
您需要 malloc
并复制每一行的缓冲区:
words[counter] = malloc(strlen(buffer)+1);
strcpy(words[counter], buffer);
不言而喻,您应该 NULL
检查 realloc
返回的值,然后再将其分配回 words
。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[]){
char buffer[103];
char **words = malloc(1 * sizeof(*words));
size_t counter = 0;
size_t array_size = 2;
for(int i = 0; i < 5; i++){
if(!fgets(buffer, 103, stdin)){
fputs("fgets failed", stderr);
}
words[counter] = buffer;
char **more_words = realloc(words, array_size * sizeof(*more_words));
words = more_words;
array_size++;
counter ++;
}
printf("********************************************************");
for(int i = 0; i < 5; i++){
printf("%s\n", words[i]);
}
}
现在这是我正在处理的简化代码。 我知道我不会处理很多可能发生的错误。
重点是,当您执行此操作时,单词数组似乎有 'last' 条目中的 5 个条目。
假设你给 fgets :
1
2
3
4
5
,然后
words[0] = 5;
words[1] = 5;
words[2] = 5;
words[3] = 5;
words[4] = 5;
为什么不是:
words[0] = 1;
words[1] = 2;
words[2] = 3;
words[3] = 4;
words[4] = 5;
?
if(!fgets(buffer, 103, stdin)){
fputs("fgets failed", stderr);
}
words[counter] = buffer;
您有一个缓冲区,每次调用 fgets
时都会被覆盖,因此 words
中的所有字符串实际上都指向同一个字符数组。试试这个:
if(!fgets(buffer, 103, stdin)){
fputs("fgets failed", stderr);
}
// here make a new buffer and copy the string just read into it.
char *new_buffer = malloc(strlen(buffer) + 1);
strcpy(new_buffer, buffer);
words[counter] = new_buffer;
问题不在于 realloc
,而是你分配给你分配的指针的内容:
words[counter] = buffer;
buffer
始终是同一个指针,所以最后一个字符串读入缓冲区。
您需要 malloc
并复制每一行的缓冲区:
words[counter] = malloc(strlen(buffer)+1);
strcpy(words[counter], buffer);
不言而喻,您应该 NULL
检查 realloc
返回的值,然后再将其分配回 words
。