【发布时间】:2015-11-12 17:49:35
【问题描述】:
完全可以肯定,我想知道以下 C++ 代码是否安全,尤其是字节序安全?我希望这个程序能够从任何计算机写入二进制文件,然后从任何其他计算机(可以具有另一个字节顺序)读取文件(即可移植)。
#include <iostream>
#include <fstream>
using namespace std;
#define BUFF_SIZE 64
template <typename type> void toBin(type value, char * buffer, size_t size);
template <typename type> type toDec(char * buffer, size_t size);
int main()
{
long long x = 238920134300912;
char * buffer = (char*)calloc(BUFF_SIZE, sizeof(char));
// Write x
toBin<long long>(x, buffer, BUFF_SIZE);
ofstream outFile("test.bin", ios::out | ios::binary);
outFile.write(buffer, BUFF_SIZE);
outFile.close();
// -------------------------------------------------------------------------
// Read x (from another computer...)
ifstream inFile("test.bin", ios::in | ios::binary);
inFile.read(buffer, BUFF_SIZE);
cout << toDec<long long>(buffer, BUFF_SIZE) << endl;
inFile.close();
// Free the buffer.
free(buffer);
return 0;
}
template <typename type> void toBin(type value, char * buffer, size_t size)
{
if (sizeof(type) > size)
throw new invalid_argument("Buffer too small");
for (size_t i = 0; i < sizeof(type); i++)
buffer[i] = (value >> i * 8) & 0xff;
}
template <typename type> type toDec(char * buffer, size_t size)
{
if (sizeof(type) > size)
throw new invalid_argument("Buffer too small");
type value = 0;
for (size_t i = 0; i < sizeof(type); i++)
value += ((type)buffer[i] & 0xff) << (8 * i);
return value;
}
【问题讨论】:
-
你为什么不直接读/写二进制文件???
-
@Walter 因为那绝对是不是 endian可移植的。
-
你意识到例如
sizeof(long)在不同的机器上是不同的,对吧?您只能将其用于固定大小的类型,例如 uint32_t。 -
顺便说一下,从不抛出指针。
-
不要在 C++ 代码中使用
*alloc/free(和 C 风格的强制转换)。不。使用 RAII 或堆栈分配的变量。
标签: c++ file portability endianness