安全转换从__int64到size_t
Safe conversion from __int64 to size_t
我正在使用Visual Studio 2017在Windows OS上工作,我获得了以下功能,以确定一个SO答案之一的文件大小:
__int64 FileSize(const char *filename)
{
HANDLE hFile = CreateFile(filename, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
return -1; // error condition, could call GetLastError to find out more
}
LARGE_INTEGER size;
if (!GetFileSizeEx(hFile, &size)) {
CloseHandle(hFile);
return -1; // error condition, could call GetLastError to find out more
}
CloseHandle(hFile);
return size.QuadPart;
}
因此,正在使用它来确定文件大小,以便将内存相应地用malloc()
分配。由于函数malloc()
接受size_t
类型,因此我将FileSize()
函数的返回值分配给size_t变量,但是我收到了以下警告:
main.cpp(67):警告c4244:'初始化':从'__int64'到':: size_t'的转换,可能会丢失数据
在这种情况下,我如何安全地将文件大小存储在size_t
变量中?我知道我可以将回报值投入到size_t
并删除警告,但这会安全/正确吗?
这是非常特定于系统的。在某些系统上,size_t
可能小于int64_t
,这会发出警告。但是,当然,无论如何,您都不能超越size_t
内的东西。
最有可能安全执行size_t s = (size_t)some_int64;
。
但是,如果您感到偏执,可以添加检查/断言:
#include <stdint.h>
...
if(some_int64 > SIZE_MAX) // this line is fully portable
{
halt_and_catch_fire();
}
SIZE_MAX
是一个常数,代表size_t
变量可容纳的最大值。
size_t类型已实现定义。因此,无法确保可以将__int64的值安全存储在size_t类型中。我建议使用static_assert:
static_assert(sizeof(__int64)<=sizeof(size_t),
"Unable to safely store an __int64 value in a size_t variable");
如果size_t小于__int64,这将在编译过程中造成错误。
请参阅http://en.cppreference.com/w/cpp/types/size_t有关更多信息。
size_t
在编译32位应用程序时小于__int64
。
如果您知道正在使用的文件是"小"(&lt; 2 gb),则可以通过铸造来稍微回避问题,如果文件很大,则可以中止:
UINT64 size = FileSize(...);
if (size > ~(size_t)0) // You might want to use SIZE_MAX instead of the ~ trick if you want to stay portable
{
printf("File is too large!n");
}
else
{
void*data = malloc((size_t) size);
if (!data)
printf("Out of memory, file is too large?n");
else
...
}
另一方面,如果文件可能很大,那么您不能假设您将能够立即将整个内容读入内存,因为机器可能没有足够的内存,或者您可能会耗尽地址空间在32位Windows过程中2 GB)。在这种情况下,您应该使用较小视图的内存映射文件。
如果您要编译32位,则size_t
仅为32位。
因此,建议您返回size.LowPart
,如果size.HighPart
不是零,则忽略或错误。
- 从不同线程使用int64的不同字节安全吗
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 大于65535的C++数组[size]引发不一致的溢出
- 为什么(-1)%vector::size()总是返回0
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 循环中的条件:为什么每次都调用strlen(),而vector.size()只调用一次
- 为什么这个 std::queue/指向结构的指针列表直到 List.Size() == 0 才释放内存?
- 在函数中使用 const int size 参数创建数组会在 Visual Studio 中抛出错误 C++:表达式的计
- vector.size() 在比较中意外工作
- vector.back() 和 vector[vector.size() - 1] 之间的区别?
- 返回 str vs. str.substr(0,str.size()) 在 leetcode 中给了我不同的输出
- 为什么 GCC 不能假设 std::vector::size 在这个循环中不会改变?
- 为什么"(!v.empty())"比"(v.size() >0)"好?
- 迭代器库中的 std::size() 不适用于传递给函数的 C 样式数组
- std::string.size() 未知行为
- 为什么gmp会在这里与"invalid next size"重新定位一起崩溃?
- 你能把一个向量<int64>投射到一个向量<uint8>吗
- 为什么我会"Invalid read of size 8"?(瓦尔格林德)
- 从 std::string 到 std::array<char,size> 的 memcopy 额外数据是否是一种未定义的行为?
- 使用 std::size 来自非 const 上下文