我正在尝试将char *存储到struct的char *字段中。我尝试了不同的东西,但没有一个有效。有问题的代码如下所示:
pInfo是struct PlayerInfo的对象。
PlayerInfo *pInfo = (PlayerInfo*)malloc(sizeof(PlayerInfo));
我从GetAddress获取的char *存储在PlayerInfo的地址字段中。
pInfo->Address = GetAddress(pInfo->playerId);
GetAddress函数如下所示。它将整数转换为字符串,将它们存储在向量中,并使用& retChar [0]将向量作为char *返回。
char* GetAddress(int playerId)
{
std::string strPlayerId = std::to_string(playerId);
std::string strGroupId = std::to_string(group.GetGroupId());
std::string retAddress = strPlayerId + ":" + strGroupId + ":" + GenRandomChar();
//From -- http://stackoverflow.com/questions/347949/convert-stdstring-to-const-char-or-char
std::vector<char> retChar(retAddress.begin(), retAddress.end());
retChar.push_back('\0');
for(std::vector<char>::const_iterator i = retChar.begin(); i != retChar.end(); ++i)
std::cout << "retChar is " << *i << std::endl;
return &retChar[0];
}
当我打印内容时,只打印垃圾。我尝试从gdb打印内存内容,但这也无济于事。
char* address = GetAddress(pInfo->playerId);
std::cout << "address is " << *address << std::endl;
std::cout << "address is " << pInfo->Address << std::endl;
std::cout << "address is " << *(pInfo->Address) << std::endl;
答案 0 :(得分:4)
问题是,你的函数范围是局部变量
std::vector<char> retChar;
超出范围并在函数返回后被销毁。
因此,使用返回的指针return &retChar[0];
调用未定义的行为。
更好的选择是将指针传递给复制数据作为参考
void GetAddress(int playerId, char*& result) {
std::vector<char> retChar;
// ...
std::copy(retChar.begin(),result);
}
并确保result
缓冲区足以接收复制的数据。
注意:强>
以上建议只解决了当前问题的第一级。可能更好的想法是改变你的函数只是为了处理std::string
而不是使用std::vector<char>
和原始char*
指针(如果你的用例允许重构这个):
将PlayerInfo::Address
成员设为std::string
类型
struct PlayerInfo {
// ...
std::string Address;
};
并定义您的GetAddress()
函数,如下所示
std::string GetAddress(int playerId) {
std::ostringstream result;
result << playerId << ":" group.GetGroupId() << ":" << GenRandomChar();
return result.str();
}
并使用结果std::string::c_str()
方法,如果您确实需要const char*
值将其传递到其他位置。
答案 1 :(得分:3)
我认为在How to convert a std::string to const char* or char*?的选定答案中使用std::vector<char>
的想法是std::vector<char>
是你的可写字符数组,而不是你应该提取一个char *
。 (但是,您可以将内容复制到由char *
标识的其他内存位置,如您所见。)
但我会问你为什么要在char *
成员Address
中存储PlayerInfo
。为什么不将该成员设为std::string
并将getAddress()
的返回类型更改为std::string
,在这种情况下,getAddress
只能返回retAddress
?< / p>
或者,您可以像这样声明getAddress
:void getAddress(int playerId, std::string& retAddress)
并且函数内部的代码更简单,因为您不必将retAddress
声明为局部变量功能