【发布时间】:2021-08-12 08:07:07
【问题描述】:
我目前正在创建一个程序来捕获用户的按键并将它们存储在一个字符串中。我希望存储按键的字符串是动态的,但我遇到了一个问题。 我当前的代码如下所示:
#include <stdio.h>
#include <stdlib.h>
typedef struct Foo {
const char* str;
int size;
} Foo;
int main(void)
{
int i;
Foo foo;
foo.str = NULL;
foo.size = 0;
for (;;) {
for (i = 8; i <= 190; i++) {
if (GetAsyncKeyState(i) == -32767) { // if key is pressed
foo.str = (char*)realloc(foo.str, (foo.size + 1) * sizeof(char)); // Access violation reading location xxx
sprintf(foo.str, "%s%c", foo.str, (char)i);
foo.size++;
}
}
}
return 0;
}
任何帮助将不胜感激,因为我没有任何想法了。 :(
我是否也应该动态分配 Foo 对象?
【问题讨论】:
-
sprintf(foo.str, "%s%c", foo.str, (char)i);。问问你自己 - 调用foo.str时的内容是什么?如果答案每次都不是“有效的 NUL 终止的 C 字符串”,则行为未定义。而且您不必看得太远 - 甚至只需在第一次通话时进行该练习。 -
附带说明:正如
GetAsyncKeyState的文档中所述,您不应该使用返回值的最低有效位,因为它不可靠并且仅存在于向后兼容16 位 Windows。 -
附带说明:在busy-wait 中使用
GetAsyncKeyState并不是等待用户输入的好方法,因为这会导致一个CPU 100% 使用CPU,从而阻止其他线程和使用该 CPU 的进程。也会增加耗电量。如果您正在编写一个图形 Windows 应用程序,您应该创建一个适当的消息循环。如果您正在编写 Windows 控制台应用程序,则应改用ReadConsoleInput。 -
旁白:如果
realloc()失败,您会泄漏内存。始终使用 tmp 指针来验证realloc()的结果,并且仅在成功时将其分配回您的主指针(失败时您的主指针仍然存在,然后由您决定如何处理错误)
标签: c string memory-leaks dynamic-memory-allocation