我有一个非常奇怪的问题。 这是我的代码: 头文件
namespace test
{
class LoadConfigData
{
struct control_params
{
char active[];
char suspended[];
char erased[];
}*ctrl_params;
bool loadConfig();
};
};
Main.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
这意味着它正在为每个结构成员打印最后复制的字符串。 我的代码有什么问题。
答案 0 :(得分:1)
问题在于您使用sprintf
。 sprintf
不会为您分配任何内存,active
,suspended
和erased
指向奇怪且未定义的地址。您正在调用未定义的行为。
如果不添加所有通常必要的细节,请使用std::string
,而不是运算符重载。对于简单的解析,请使用流。现在,完全避免使用任何C字符串函数,而只使用C ++。
答案 1 :(得分:1)
问题是你不给字符数组一个大小:
struct control_params
{
char active[];
char suspended[];
char erased[];
}*ctrl_params;
我很惊讶这个编译;我的理解是一个unsized数组是一个不完整的类型,因此不能是一个非静态的类成员。但是,我的编译器至少(并且可能是你的)将这些视为大小为零的数组,所有这些都在内存中的相同位置。因此,每次你写一个它都会覆盖你写给其他人的任何东西。 (当然,行为是未定义的,因为它写在数组边界之外)。
最简单的解决方案是使用std::string
来表示字符串。这将自动管理它的大小,你可以简单地写active = a
而不是弄乱sprintf
(或者,更明智地,strncpy
),并希望你没有得到缓冲区溢出