-1

我有一个非常奇怪的问题。这是我的代码:头文件

namespace test
{
class LoadConfigData
{

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

主文件

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;

我很惊讶这个编译;我的理解是,未调整大小的数组是不完整的类型,因此不能是非静态类成员。但是,我的编译器至少(可能是你的)将它们视为大小为零的数组,所有这些都位于内存中的同一位置。因此,每次你写一个,它都会覆盖你写给其他人的任何东西。(当然,行为是未定义的,因为它写在数组边界之外)。

最简单的解决方案是使用std::string来表示字符串。这将自动管理其大小,您可以简单地编写active = a而不是乱七八糟sprintf(或者,稍微更明智的是,strncpy)并希望您不会遇到缓冲区溢出。

于 2013-08-16T13:18:29.937 回答
1

问题是您对sprintf. sprintf不会为您分配任何内存activesuspended并且erased指向奇怪和未定义的地址。您正在调用未定义的行为。

在不添加所有通常必要的细节的情况下,使用std::string它的运算符重载来代替。对于简单的解析,请使用流。目前,完全避免使用任何 C 字符串函数,而只使用 C++。

于 2013-08-16T13:01:19.063 回答