gpt4 book ai didi

c - C中的显示缓冲区

转载 作者:行者123 更新时间:2023-11-30 21:31:20 24 4
gpt4 key购买 nike

我正在尝试显示缓冲区,但它显示的是特殊字符。这是我的代码:

size_t write(int fd, const void *buf, size_t count)
{

static size_t (*write_func)(int, const void *, size_t) = NULL;
if (!write_func)
write_func = (size_t(*)(int, const void *, size_t)) dlsym(RTLD_NEXT, "write");


char tmp[count];

memcpy(tmp,buf,count);
printf(" %c \n",tmp[1]);

您对如何解决这个问题有什么想法吗?非常感谢!

最佳答案

您在堆栈上分配只读数据的副本。这是危险的,因为堆栈空间可能是有限的。 (在 Linux 中,只有原始堆栈会动态增长;线程堆栈的大小是固定的,而且通常很小。)

然后使用stdio.h printf() 函数将指定数据的第二个字节(即使count 可能为1)输出到标准输出,因此无论如何,您可能会访问临时数组之外的内容。

大多数 printf() 实现在内部调用 write() 来刷新缓冲区。根据链接的不同,这可能最终会递归(您的函数调用 printf ,它调用您的函数,该函数调用 printf 等等),耗尽进程可用的所有 RAM ,然后崩溃。

以上都没有意义。

首先,如果您需要复制输入数据,请使用 malloc()memcpy() 动态执行,然后使用 free() > 之后。这样,您就不会突然开始导致多线程程序崩溃(其中堆栈空间是有限的,并且对于 Linux 中除原始进程之外的所有进程都是固定的)。

其次,您需要使用通过链接器获得的原始write_func

第三,需要保留errno以避免客户端程序出现不可预见的问题。只需使用一个临时的本地int来存储它即可。请记住,不仅 write()malloc()free() 也可能修改 errno,并且您必须对调用者隐藏这些更改。

第四,write()的返回类型是ssize_t,而不是size_t。前者已签名,后者可能未签名。

第五,始终允许短写入。你永远不能依赖于获得一个“完整”的 block ;应用程序进行内部处理,特别是在使用套接字时,以奇数大小刷新它(特别是 TCP/IP 和 UDP/IP 的 MTU 的倍数)。您对输入/输出的“修改”必须是无状态的。更糟糕的是,如果您的修改更改了缓冲区长度,并且描述符是非阻塞的,并且 write_func() 调用会在修改部分的中间返回一个简短的写入,而该部分不会合理地映射到任何原始字节,你打算怎么处理?实际上,您无法重试,因为描述符是非阻塞的;原始应用程序可能会挂起 - 例如,如果以协进程方式使用,同时从具有严格排序要求的对等进程发送和接收数据 - 因为当应用程序逻辑级别不允许写入时,您的添加将重新发出写入。

简单来说,你的计划行不通。您可能会让它与某些特定的简单应用程序一起工作,但它可能会严重破坏其他应用程序。无论您想实现什么目标,都有更好的方法。

我希望我没有太直言不讳,但我认真建议您首先了解低级 POSIX I/O 的细节,然后再围绕它们创建包装器。 Linux man-pages project是我可以推荐的一个很好的引用,但我认为您可能需要先从一些教程开始。

关于c - C中的显示缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11335133/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com