2016-12-22 7 views
1

文字列のベクトルを最初にchar *の配列で初期化してベクトルに変換しようとしています。しかし、次のコードは機能しません、ベクトルは3つの同じ最初の文字列と4番目、5番目、6番目の文字列を持つことになりました。文字列のベクトル配列を初期化するときのエラー

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 

文字列が5つだけの場合、コードは正常に動作します。配列をベクトルに代入しないと、正常に表示されます。ベクトルに代入する前に、x_joint_names_charのすべての内容が正しいことを確認してください。原因は何ですか?

初期化コードは、この記事に基づいています:Initialize a vector array of strings

編集: は以下にも作品のような文字列にhand_lrを移動します。

答えて

4

行の初期化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の配列にします。またはpush_back各文字列をベクターに入れ、配列を削除します。