将uint16_t投射到wchar_t的安全方法
Safe way to cast a uint16_t to a wchar_t
试图清理一些代码,我想知道以下内容是否是将uint16_t转换为wchar_t的安全方法。
#if ! defined(MARKUP_SIZEOFWCHAR)
#if __SIZEOF_WCHAR_T__ == 4 || __WCHAR_MAX__ > 0x10000
#define MARKUP_SIZEOFWCHAR 4
#else
#define MARKUP_SIZEOFWCHAR 2
#endif
void FileReader::parseBuffer(char * buffer, int length)
{
//start by looking for a vrsn
//Header seek around for a vrns followed by 32 bit size descriptor
//read 32 bits at a time
int cursor = 0;
char vrsn[5] = "vrsn";
cursor = this->searchForMarker(cursor, length, vrsn, buffer);
int32_t size = this->getObjectSizeForMarker(cursor, length, buffer);
cursor = cursor + 7; //advance cursor past marker and size
wchar_t *version = this->getObjectForSizeAndCursor(size, cursor, buffer);
wcout << version;
delete[] version; //this pointer is dest from getObjectForSizeAndCursor
}
-
wchar_t* FileReader::getObjectForSizeAndCursor(int32_t size, int cursor, char *buffer) {
int wlen = size/2;
uint32_t *dest = new uint32_t[wlen+1];
unsigned char *ptr = (unsigned char *)(buffer + cursor);
for(int i=0; i<wlen; i++) {
#if MARKUP_SIZEOFWCHAR == 4 // sizeof(wchar_t) == 4
char padding[2] = {' ',' '};
dest[i] = (padding[0] << 24) + (padding[1] << 16) + (ptr[0] << 8) + ptr[1];
#else // sizeof(wchar_t) == 2
dest[i] = (ptr[0] << 8) + ptr[1];
#endif
ptr += 2;
cout << ptr;
}
return (wchar_t *)dest;
}
使用填充的方式是否有任何范围问题? 当我在调用函数中delete dest[]
时,填充会泄漏吗?
区别
#if MARKUP_SIZEOFWCHAR == 4 // sizeof(wchar_t) == 4
char padding[2] = {' ',' '};
dest[i] = (padding[0] << 24) + (padding[1] << 16) + (ptr[0] << 8) + ptr[1];
#else // sizeof(wchar_t) == 2
dest[i] = (ptr[0] << 8) + ptr[1];
#endif
是完全没有必要的。 padding[i]
为 0,因此向左移动使其保持 0,添加它不起作用。
编译器可能会也可能不会优化每个循环迭代中padding
的双字节数组的分配,但由于它是一个自动数组,因此它不会以任何方式泄漏。
由于循环中使用的类型是无符号的,因此只需使用
dest[i] = (ptr[0] << 8) + ptr[1];
是绝对安全的。(字节序当然必须是正确的。
为
return (wchar_t *)dest;
你应该让dest
的类型取决于wchar_t
的大小,如果sizeof(wchar_t) == 2
(和CHAR_BIT == 8
),它应该是uint16_t*
的。
你尝试做的事情是行不通的。它在几个方面被打破了,但让我们专注于演员阵容。
您的问题与您的代码不匹配。您的代码正在使用uint32_t
,而您的问题询问的是uint16_t
。但这并不重要,因为两者都行不通。
如果需要使用 wchar_t
,那么实际上应该使用 wchar_t
。如果您的目标是获取char*
的两个连续字节并将它们复制到wchar_t
的前两个字节中,那么就这样做吧。
这是一个更好的代码版本,一个实际有效的版本(在某种程度上,从char*
复制两个字节并假装它是一个wchar_t
是有意义的):
std::wstring FileReader::getObjectForSizeAndCursor(int32_t size, int cursor, char *buffer) {
int wlen = size/2;
std::wstring out(wlen);
unsigned char *ptr = (unsigned char *)(buffer + cursor);
for(int i=0; i<wlen; i++) {
out[i] = (ptr[0] << 8) + ptr[1];
ptr += 2;
cout << ptr;
}
return out;
}
另外,没有内存泄漏的机会,因为我们使用的是像 std::wstring
这样的适当 RAII 类。
相关文章:
- 将传入的网络"char*"数据转换为"uint8_t"并返回的安全方法是什么?
- 在 c++ 中从执行的 shell 命令获取返回状态的安全方法是什么?
- 在C++线程内实现多个计时器的最安全方法
- 最有效的安全方法将 std::map<int, std::shared_ptr> 转换为 std::<Base>map<int, std::shared_ptr<D
- 重新分配指针阵列的一部分的安全方法
- 将整数添加到数组值而无需调用它的最安全方法
- 使用括号运算符实现矩阵类的安全方法
- 将空隙动态铸造到类型的安全方法?
- C/通过套接字发送time_t的最安全方法
- 交换两个类实例的最安全方法
- 将uint16_t投射到wchar_t的安全方法
- 从字符串中读取溢出双倍作为'inf'的安全方法
- 期货是检查单个线程完成情况的安全方法吗
- 在C++中动态分配向量的安全方法是什么
- 在C++类中构建互斥保护的线程安全方法
- C++和跳出动态生成代码的安全方法
- 这是实现错误处理的安全方法吗
- 将长整数转换为字符数组的最安全方法是什么
- 缓存 PID 到端口映射窗口的安全方法
- 将无符号长整整除以无符号长整型的最安全方法