'uintmax_t'到'size_t'和'unsigned int'转换的数据丢失是多少?

时间:2011-10-09 19:59:42

标签: c++ boost int

我明白了:

  

警告C4244:'初始化':从'uintmax_t'转换为'unsigned int',可能丢失数据

在:

boost::shared_array<char> buffer( new char[file->size]);

...然后这个:

  

警告C4244:'参数':从'uintmax_t'转换为'size_t',可能会丢失数据

在:

boost::asio::write(*socket, boost::asio::buffer(buffer.get(), file->size));

我会害怕还是没事?

3 个答案:

答案 0 :(得分:4)

可能file->size的类型为uintmax_t,大于size_t operator new[]占用的数组大小。通常,第一个可能是64位整数,而第二个只能是32位。

实际上,当您尝试处理超过4GB的文件时,这会导致问题,因为size_t不能代表如此大量的字节。如果您只希望处理size_t足以存储文件大小的较小文件,则不会出现问题。

答案 1 :(得分:3)

这取决于实施。

uintmax_t是实现提供的最大无符号类型。 size_tsizeof运算符的结果类型,大小足以容纳任何对象的大小。当然,unsigned intint类型的无符号版本。

唯一的保证是size_tunsigned int都至少为16位(但可能更大),uintmax_t至少为64位(假设C99规则),并且uintmax_t至少与任何其他无符号类型一样宽。

大概file->size是文件的大小(以字节为单位),它可能是uintmax_t类型。根据系统的不同,文件的最大大小可能会大于内存中任何可能对象的大小。

如果此特定文件的大小不是太大,则没有问题。但是如果size_t是32位(暗示对象不能超过4千兆字节),而你的文件是5千兆字节,那么你将无法分配足够大的内存缓冲区。保留文件的内容。

size_tSIZE_MAX的最大值仅是对象最大大小的上限。仅仅因为SIZE_MAX是2 ** 31-1,这并不一定意味着你实际上可以创建一个大的对象。

答案 2 :(得分:0)

这取决于你的文件有多大。

大多数计算机的磁盘存储空间大于RAM,并且在许多情况下可以支持单个文件太大而无法容纳到RAM中。在这种情况下,分配可能会失败,或者文件大小可能会被截断为指针的大小,在这种情况下,您将分配一个不足以容纳文件的缓冲区。

您可以使用以下方法检测尺寸过大的文件:

size_t buffersize(file->size);
if (buffersize != file->size) { /* error, file too large to fit into virtual memory */ }
/* use buffersize for buffer allocation */

这也会使警告消失。