gpt4 book ai didi

C++ vector 插入新对象

转载 作者:太空狗 更新时间:2023-10-29 20:21:56 26 4
gpt4 key购买 nike

我是一名自学成才的 c++ 程序员(仍处于新手级别)。

我想我对 C++ 的工作原理有所了解,但我无法解决这个问题:我想用我定义的类的不同元素创建和填充 std::vector:

// other code

while (getline(cfgDataStream, cfgData)) //parsing cycle of the config file
{

std::stringstream ss(cfgData); //creating a stream in order to fill fields
ss >> string1 >> IP1 >> IP2 >> PORT2 >> INDEX;
//they are all strings save the last one, which is a int
if (ss.fail())
{
//bad things happen
}

//FIRST IDEA: Using insert()

CModbusServer MBtemp* = new CModbusServer(this, IP2.c_str(), PORT2, INDEX)
std::vector<CModbusServer*>::iterator iterator = this->m_pServerCollection.begin(); //I get the vector initial position

m_pServerCollection.insert(iterator + (INDEX), MBTemp); // I put the new object in the right index (I don't trust the order in the config file)


//SECOND IDEA: Using push_back()

m_pServerCollection.push_back( new CModbusServer(this, IP2.c_str(), PORT2, INDEX)); //I attach each new object to the end of vector (i trust the order in the config file)
}

基本上我想创建一个 CModbusServer 对象并将其指针插入一个 vector 中,这样我在每个 vector 位置都有 n 个不同的 CModbusServer 对象。这就是我迷路的地方,我尝试了两种插入方式(如代码所示)但没有成功。

CModbusServer 有一个 const char* ipAddress 字段。如果我尝试访问该字段(即在 .Format(_T("%S)) 函数中使用它),我会得到随机数据。试图了解为什么我注意到在 vector 中我没有 n 个不同的对象,而是用 new CModbusServer(this, IP2.c_str(), PORT2, INDEX) 创建的最后一个对象的 n 个拷贝.发生这种情况的原因可能是我有一个指针 vector ,但这些应该是指向不同对象的指针......

我正在使用 Visual Studio 2015 和 MFC 来实现基于对话框的应用程序。我有一个 AppEngine 类,它从其他类调用方法并有一个 CModbusServer 元素 vector 。CModbusServer.h如下:

class CModbusServer
{
public:
CModbusServer(void *parentEngine, const char* , unsigned short , int );
~CModbusServer();
const char* ipAddress;
unsigned short port;
int indNode;
modbus_t *MBserver;
bool isConnected;
}

所以,我的问题是:

1) 为什么我不能访问 ipAddress 字段(而不是读取“192.0.2.1”我读取随机字符)而我理论上应该能够使用 theApp.CModbusServerVector[properIndex]->ipAddress 读取它?

2) 我在填充 vector 时犯了一个错误,但我看不出错误在哪里,最重要的是,为什么错误。

感谢您的帮助,请原谅我的英语和任何遗漏。

编辑:

CModbusServer的构造函数代码是这样的:

CModbusServer::CModbusServer(void *pE, const char* ip, unsigned short nport, int ind)
: parentEngine(pE), //used in order to keep track of the parent dialog
ipAddress(ip),
port(nport),
indNode(ind)
{
this->isConnected = false;
this->m_socket = INVALID_SOCKET;

memset(&m_socketstructhint, 0, sizeof m_socketstructhint);
m_socketstructhint.ai_family = AF_UNSPEC;
m_socketstructhint.ai_socktype = SOCK_STREAM;
m_socketstructhint.ai_protocol = IPPROTO_TCP;

MBserver = modbus_new_tcp(ipAddress, (int)nport);


}

如果我遗漏了任何其他有用的信息,请告诉我。

最初我使用 CString用于管理字符串,但后来我遇到了越来越多的问题,最后得到了一个编译和耐心工作的代码 const char* .我设法建立了一个连接并读取了所需的 modbus 寄存器,但后来我陷入了 isAddress 打印问题。

modbus_new_tc(ip,port)是在 libmodbus 库中找到的一种方法,这是一个我必须使用的为 C 编写的免费软件库。

编辑 2:与 angew 答案相关:

所以,如果我是对的,那么我创建了一组临时指针,供构造函数使用(我现在添加了相关代码)。但是构造的对象不应该与我作为参数传递的内容无关吗?那些论点不是被复制了吗?对不起,如果这个问题很愚蠢,但我还在学习。

索引是连续的,尽管在配置文件中它们也可以是 0-1-2-3(每行 1 个)或 0-3-1-2,这就是我所说的“不要相信它们”的意思".

push_back方法有同样的问题,可能问题又回到了构造函数中。令我困惑的是,通过逐步执行,我可以看到在 while 循环的每次迭代中,我都会得到新的和正确的数据,但不是放在第 i 个位置,而是放在第 i 个位置(即:原始数据:a b c,第 1 次运行 vector = a;第 2 次运行 vector = b b,第 3 次运行 vector = c c c)

我不知道std::unique_ptr<> ,我会查一下。

我试过使用 std:string 甚至 CString,但问题出在 libmodbus 库之下。

最佳答案

调用 c_strstd::string 上返回一个指向存储在 std::string 中的内部数据的“实时”指针实例。返回的指针指向一个缓冲区,该缓冲区仅在 std::string 期间有效。它被调用的地方仍然存在并且未被修改。

CExtracalModbusServer 的构造函数只存储传入的指针。一旦IP2,该指针就会悬空。在输入循环的下一次迭代中重新分配。 (指向的地址仍然是相同的,但是之前位于该地址的缓冲区已被覆盖、释放或其他原因。换句话说,指针只是悬空)。

至于插入到 vector 中:第一种方法(使用 insert )只有在文件中的索引是连续的并且从 0 开始时才有效。 .您需要一个有效的 vector 迭代器才能插入其中,此处有效意味着指向 vector 中已有的元素之一,或者指向末尾迭代器(由 end() 返回的迭代器)。如果INDEX等于或大于 vector 的大小,则m_pServerCollection.insert(iterator + (INDEX), MBTemp);将尝试插入 vector 外部(本质上是缓冲区溢出)。超精细的行为随之而来。

push_back插入数据的方式应该可行,如果您发现它行为不当,它要么是早期错误(带有悬垂指针的错误)的产物,要么代码中存在您未显示的单独问题。


与手头的问题无关,但代码包含手动管理动态内存形式的非常糟糕的做法。而不是存储 CModbusServer*在 vector 中并使用 delete 手动管理内存在所有正确的地方,你应该使用 std::unique_ptr<CModbusServer>它将为您处理适当的重新分配,即使存在异常也是如此。

如果CModbusServer在你的控制之下,你同样应该改变它来存储一个 std::string而不是 const char* .永远不要在 C++ 中使用 C 风格的字符串,除非你必须与 C 风格的 API 交互,即使在这种情况下,也只能将它们的使用限制在交互本身。再次强调相同的原则:不要手动管理内存。

关于C++ vector 插入新对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40463865/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com