【发布时间】:2021-03-26 11:19:01
【问题描述】:
这里是一个业余爱好者,很抱歉提出这个问题。
我一直在尝试做 K&R ex。 1-13 但具有动态内存分配和指针。 K&R前。 1-13:“编写一个程序来打印输入中单词长度的直方图。水平条形很容易绘制直方图;垂直方向更具挑战性。”
因为我使用的是Windows,所以我将书中使用的EOF替换为主循环条件下的'q',后者必须与预期的最后一个单词用空格隔开。
在没有执行带有 realloc 的块语句之前,一切都运行良好。因此,如果输入是没有引号的“stackoverflow 是最好的 q”,则条形图会正确显示,因为字数 (4) 可以存储在最初分配的内存中(5 个块)。但是,如果输入包含超过 5 个单词,则结果是无限循环。有人可以解释一下做错了什么吗?
#include <stdio.h>
#include <stdlib.h>
static void exit_if_null_ptr(int* x) {
if (NULL == x) {
printf("memory allocation error!");
exit(-1);
}
}
static void draw_histogram_horizontal(int* length_of_words, int word_count) {
for(int i = 0; i < word_count; i++) {
int tmp = *(length_of_words + i);
while (tmp) {
printf("*");
tmp--;
};
printf("\n");
}
}
static void histogram_word_length(void) {
char c = '\0';
int word_count = 0, // also offset to length_of_words pointer
inside_word = 0;
size_t mem_blocks = 5;
int* length_of_words = (int*)calloc(mem_blocks, sizeof(int));
exit_if_null_ptr(length_of_words);
while ('q' != (c = getchar())) {
if (' ' == c || '\t' == c || '\n' == c) {
if (inside_word) {
inside_word = 0;
word_count++;
if (word_count == (int)mem_blocks) {
mem_blocks += 5;
length_of_words = (int*)realloc(length_of_words, mem_blocks);
exit_if_null_ptr(length_of_words);
}
}
}
else {
inside_word = 1;
*(length_of_words + word_count) += 1;
}
}
draw_histogram_horizontal(length_of_words, word_count);
free(length_of_words);
}
int main(void) {
histogram_word_length();
return 0;
}
【问题讨论】:
-
如果 realloc 失败,length_of_words 将被赋值为 NULL,但原始值没有被释放。
-
realloc的大小似乎也不正确:增加分配需要很多 bytes,而 calloc 需要很多 blocks指定的大小。混合它们似乎是一个糟糕的主意,你应该在这两种情况下都使用realloc。另一个问题是realloc没有将其内存归零,因此额外的内存未初始化,从中读取的是 UB。 -
我无法重现该问题:
echo 'stackoverflow is the very best a q'| ./a.out给了我 6 个小节。请使用触发错误的输入更新问题。 -
realloc不会将新内存归零。
标签: c