初始化字符串矢量阵列时的错误

Error when initializing a vector array of strings

本文关键字:错误 阵列 字符串 初始化      更新时间:2023-10-16

我试图通过在char*数组中初始化字符串来初始化字符串向量,然后将它们转换为向量。但是,以下代码不起作用,矢量最终具有相同的第一个字符串,第五和第六字符串。

string hand_lr_ = "left";
const char* x_joint_names_char[] = {("r2/"+hand_lr_+"_arm/wrist/yaw").c_str(),("r2/"+hand_lr_+"_arm/wrist/pitch").c_str(),("r2/"+hand_lr_+"_arm/hand/index/distal").c_str(),("r2/"+hand_lr_+"_arm/hand/ringlittle/ringMedial").c_str(),("r2/"+hand_lr_+"_arm/hand/ringlittle/ringDistal").c_str(),("r2/"+hand_lr_+"_arm/hand/ringlittle/ring").c_str() };
std::vector<std::string> x_joint_names(x_joint_names_char, x_joint_names_char + sizeof(x_joint_names_char)/sizeof(x_joint_names_char[0]));
for (int i =0; i < sizeof(x_joint_names_char)/sizeof(x_joint_names_char[0]) ;i++) {
  cout << x_joint_names[i] << endl;
  for (int j = 0; j < strlen(x_joint_names_char[i]); j++)
  {
    cout << x_joint_names_char[i][j];
  }
  cout << endl;
}

上面的代码输出以下内容。

出现怪异的角色的地方。
r2/left_arm/wrist/yaw
8�{
r2/left_arm/wrist/yaw
r2/left_arm/wrist/yaw
r2/left_arm/wrist/yaw
r2/left_arm/wrist/yaw
r2/left_arm/hand/ringlittle/ringMedial
r2/left_arm/hand/ringlittle/ringMedial
r2/left_arm/hand/ringlittle/ringDistal
r2/left_arm/hand/ringlittle/ringDistal
r2/left_arm/hand/ringlittle/ring
r2/left_arm/hand/ringlittle/ring

如果只有五个字符串,则代码正常工作。如果我不将数组分配给向量,也看起来很正常。X_JOINT_NAMES_CHAR中的所有内容在分配给向量之前都是正确的。知道什么原因是什么?

初始化代码基于此文章:初始化字符串的向量阵列

编辑: 将手_lr移动到字符串中也有效。

const char* x_joint_names_char[] = {("r2/left_arm/wrist/yaw"),("r2/left_arm/wrist/pitch"),("r2/left_arm/hand/index/distal"),("r2/left_arm/hand/ringlittle/ringMedial"),("r2/left_arm/hand/ringlittle/ringDistal"),("r2/left_arm/hand/ringlittle/ring") };

初始化 x_joint_names_char的行会产生一堆悬空的指针。

表达式("r2/"+hand_lr_+"_arm/wrist/yaw")表示临时字符串(因为它没有名称并且没有动态分配)。c_str()功能会产生一个指向临时字符串的指针,但是当该行完成时,该行上的临时字符串都被破坏了。

在链接线程中使用char *是一个微观优化,只有在初始化器为C风格的字符串文字时才能使用。

由于C 11您可以写:

std::vector<std::string> x_joint_names = {
    "r2/"+hand_lr_+"_arm/wrist/yaw",
    "r2/"+hand_lr_+"_arm/wrist/pitch",
    "r2/"+hand_lr_+"_arm/hand/index/distal"
};

例如。如果您被迫使用旧编译器,则将您的初步数组成为string的数组,而不是const char *的数组。或push_back每个字符串进入向量并取消数组。