memcpy / memset等可以处理的缓冲区的最大大小是多少?

memcpy和其他函数可以处理的缓冲区的最大大小是多少? 这种实现依赖吗? 这是否受到作为参数传入的大小(size_t)的限制?

这完全取决于实现。

这取决于硬件和任何东西,但也取决于编译器的时代。 对于任何拥有相当现代编译器的人(意味着任何基于90年代或更晚的标准的东西),size参数是size_t 。 这可以合理地是最大的16位无符号,最大的32位无符号或最大的64位无符号,具体取决于编译器编译的内存模型。 在这种情况下,您只需要找出size_t在您的实现中的大小。 但是,对于非常旧的编译器(即ANSI-C之前, 也许是某些早期版本的ANSI C ),所有的赌注都是关闭的。

例如,在标准方面,查看cygwin和Solaris 7,size参数是size_t 。 查看我可用的嵌入式系统,size参数是unsigned (意思是16位无符号)。 (这个嵌入式系统的编译器是在80年代编写的。)我找到了一些对某些ANSI C的Web引用, 其中size参数是一个int

您可能希望在size_t上看到这篇文章以及关于某些早期GCC版本错误特征的后续文章 ,其中size_t被错误地签名。

总之,对于几乎每个人来说size_t将是正确的使用参考。 但是,对于那些使用嵌入式系统或旧系统编译器的旧系统的人来说,需要检查手册页。

函数通常使用size_t来传递大小作为参数。 我通常说因为fgets()使用了一个int参数,在我看来这是C标准中的一个缺陷。

size_t被定义为一种类型,它可以包含您可以访问的任何对象的大小(以字节为单位)。 通常它是unsigned intunsigned long的typedef。
这就是sizeof运算符返回的值为size_t类型的原因。

因此2 **( sizeof(size_t) * CHAR_BIT )为您提供了程序可以处理的最大内存量,但它肯定不是最精确的内存量。
CHAR_BITlimits.h定义,并产生char包含的位数)。

他们采用size_t参数; 所以它的平台依赖。

依赖于实现,但您可以在使用memcpy之前查看需要包含的标题(.h)文件。 声明会告诉你(寻找size_t或其他)。

然后你问大小是什么,嗯,这是依赖于实现的部分。

是的,你不能复制大于2 ^(sizeof(size_t)* 8)字节的区域。 但这没什么好担心的,因为你也不能分配更多的空间,因为malloc也把size作为size_t参数。

还有一个问题与size_t可以表示您的平台允许进程实际解决的内容有关。

即使在64位平台上使用虚拟内存,本周你也不太可能调用大小超过几TB的memcpy() ,即使这样,这也是一台非常热门的机器….它是很难想象一个可以安装一个完全覆盖的64位地址空间的机器是什么样的。

没关系只有几KB总可写内存的嵌入式系统,无论size_t的定义如何,尝试memcpy()信息都比RAM更有意义。 如果你这样做的话,请考虑刚刚从该通话中收到返回地址的堆栈发生了什么?

或者进程看到的虚拟地址空间小于安装的物理内存的系统。 例如,在Win64平台上运行Win32进程就是这种情况。 (我第一次在PDP-11上运行的OS TSX-11上遇到了这个问题,在每个进程中有4MB的物理内存和64KB的虚拟地址。然后4MB的RAM是大量的内存,IBM PC没有还存在。)