从 vector<unsigned char> 转换为 char* 包括垃圾数据

Posted

技术标签:

【中文标题】从 vector<unsigned char> 转换为 char* 包括垃圾数据【英文标题】:Convert from vector<unsigned char> to char* includes garbage data 【发布时间】:2020-07-13 12:21:04 【问题描述】:

我正在尝试对字符串进行 base64 解码,然后将该值转换为 char 数组以供以后使用。解码工作正常,但转换时我得到垃圾数据。

这是我目前的代码:

std::string encodedData = "VGVzdFN0cmluZw=="; //"TestString"
std::vector<BYTE> decodedData = base64_decode(encodedData);

char* decodedChar;
decodedChar = new char[decodedData.size() +1]; // +1 for the final 0
decodedChar[decodedData.size() + 1] = 0; // terminate the string
for (size_t i = 0; i < decodedData.size(); ++i) 
    decodedChar[i] = decodedData[i];

vector&lt;BYTE&gt;unsigned char BYTE 的typedef,取自this SO 答案。 base64 代码也来自这个答案(最受好评的答案,而不是接受的答案)。 当我运行此代码时,我在 VisualStudio Text Visualiser 中得到以下值:

TestStringÍ

我也尝试过其他的转换方法,比如:

char* decodedChar = reinterpret_cast< char *>(&decodedData[0]);

这给出了以下内容:

TestStringÍÍÍýýýýÝÝÝÝÝÝÝ*b4d“

为什么我在字符串末尾得到垃圾数据?我做错了什么?

编辑:澄清了我正在使用的链接问题中的哪个答案

【问题讨论】:

你链接的那些函数已经在std::string上运行 我不确定我是否遵循。我正在使用它们将 std::string 转换为 vector,然后我需要将其作为 char[]. decodedChar = new char[decodedData.size() +1]; 这个数组的有效索引是什么? decodedChar[decodedData.size() + 1] = 0 这分配给什么索引?这有效吗? 我只是要指出这一点,因为到目前为止还没有其他人这样做过:base 的全部血腥点......编码是将数据转换为可以存储在字符串中的形式,即使原始数据本身不适合存储在字符串中,因为它可能包含字符串中有效字符集之外的字节。例如空字节,它可能会终止一个字符串。 不建议从 base64 到向量再到字符串的整个练习。你应该在向量处STOP并保持在那个位置! 【参考方案1】:
char* decodedChar;
decodedChar = new char[decodedData.size() +1]; // +1 for the final 0

当您有std::string 可以为您执行此操作时,为什么要手动分配一个缓冲区然后复制到它?

只要做:

std::string encodedData = "VGVzdFN0cmluZw=="; //"TestString"
std::vector<BYTE> decodedData = base64_decode(encodedData);

std::string decodedString  decodedData.begin(), decodedData.end() ;

std::cout << decodedString << '\n';

如果您需要char *,只需使用.c_str()

const char* cstr = decodedString.c_str();

如果您需要将此传递给以char* 作为输入的函数,例如:

void someFunc(char* data);
//...
//call site
someFunc( &decodedString[0] );

我们在 C++ 中有大量的函数、抽象和容器,它们是为了改进 C 语言而设计的,这样程序员就不必在每次编码时都手动编写东西并犯同样的错误。最好尽可能使用这些功能来避免原始循环或进行类似这样的简单修改。

【讨论】:

【参考方案2】:

您正在写超出分配数组的最后一个元素,这可能会导致任何事情发生(根据 C++ 标准)。你需要decodedChar[decodedData.size()] = 0;

【讨论】:

以上是关于从 vector<unsigned char> 转换为 char* 包括垃圾数据的主要内容,如果未能解决你的问题,请参考以下文章

如何使用多次 memcpy 转换回 std::vector<unsigned char>?

使用 std::vector<unsigned char> 的内容初始化结构

Swig:将 std::vector<unsigned char> 传递给从 c++ 生成的 c# 函数

逐个保存unsigned char矢量

将二进制文件读取到“unsigned char”向量时的模板参数是啥

将 size_t 转换为向量<unsigned char>