-1

私は非常に奇妙な問題を抱えています。これが私のコードです:ヘッダーファイル

namespace test
{
class LoadConfigData
{

    struct control_params
    {
         char               active[];
         char               suspended[];
         char               erased[];        
    }*ctrl_params;
bool loadConfig();
};
};

メイン.cpp

using namespace std;
using namespace test;
namespace test
{
extern LoadConfigData           *loadConfigDataobj;
LoadConfigData *loadConfigDataobj   = new LoadConfigData;
};
int main()
{
loadConfigDataobj->loadConfig();
cout <<loadConfigDataobj->ctrl_params->active_status_code_v<<endl;
cout <<loadConfigDataobj->ctrl_params->suspended_status_code_v<<endl;
cout <<loadConfigDataobj->ctrl_params->erase_status_code_v<<endl;
return 0;
}

bool LoadConfigData::loadConfig()
{
std::string a = "AC";
std::string b = "SP";
std::string c = "ER";
LoadConfigData::ctrl_params = new LoadConfigData::control_params;
sprintf(loadConfigDataobj->ctrl_params->active,"%s",a.c_str());
sprintf(loadConfigDataobj->ctrl_params->suspended,"%s",b.c_str());
sprintf(loadConfigDataobj->ctrl_params->erased,"%s",c.c_str());
return true;
}

出力:

ER
ER
ER

これは、構造体メンバーごとに最後にコピーされた文字列を出力していることを意味します。私のコードで何が間違っていますか。

4

2 に答える 2

1

問題は、文字配列にサイズを指定しないことです。

struct control_params
{
     char               active[];
     char               suspended[];
     char               erased[];        
}*ctrl_params;

これがコンパイルされることにかなり驚いています。私の理解では、サイズのない配列は不完全な型であり、非静的クラス メンバーにはなり得ないということでした。ただし、少なくとも私のコンパイラ (およびおそらくあなたのもの) は、これらをサイズ 0 の配列として扱い、すべてメモリ内の同じ場所に配置します。したがって、1 つに書き込むたびに、他のものに書き込んだ内容が上書きされます。(もちろん、配列の範囲外に書き込むため、動作は未定義です)。

最も簡単な解決策はstd::string、文字列を表すために を使用することです。それはそのサイズを自動的に管理し、active = aいじり回すのではなくsprintf(または、もう少し賢明にstrncpy)、バッファオーバーランが発生しないことを期待するのではなく、単純に書くことができます。

于 2013-08-16T13:18:29.937 に答える
1

問題は の使い方ですsprintfsprintfはメモリを割り当てません。 はactive、奇妙で未定義のアドレスsuspendederased指しています。未定義の動作を呼び出しています。

通常必要な詳細をすべて追加せずに、std::string代わりに and it's 演算子のオーバーロードを使用します。単純な解析には、ストリームを使用します。今のところ、C 文字列関数を完全に避け、代わりに C++ のみを使用してください。

于 2013-08-16T13:01:19.063 に答える