我认为我错过了一些关于指针的基本内容。我有以下代码:
alicat_data *data = (alicat_data*)ent.second->get_data();
if(ent.first == "AlicatA"){
ui->ac0_P->setValue(data->pressure);
ui->ac0_T->setValue(data->temperature);
ui->ac0_Q->setValue(data->flow_rate);
ui->ac0_Q0->setValue(data->mass_flow_rate);
ui->ac0_Qsp->setValue(data->setpoint);
}引用定义为以下结构的结构:
struct alicat_data : Data {
float pressure; /** Pressure in mb */
float temperature; /** Temperature in degC */
float flow_rate; /** Volumetric low rate; units are defined by the model */
float mass_flow_rate; /** Mass flow rate; units are defined by the model */
float setpoint; /** Device setpoint (if it is a controller); units are defined by the model */
gas gas_; /** Enum as defined above representing the gas */
alicat_data(float p = 0, float T = 0, float Q = 0,
float Q0 = 0, float sp = 0, gas g = Air):pressure(p),
temperature(T), flow_rate(Q), mass_flow_rate(Q0),
setpoint(sp), gas_(g){
setTime();
}
virtual std::string serialize2ascii(){return std::to_string(pressure)
+ "\t" + std::to_string(temperature)
+ "\t" + std::to_string(flow_rate) + "\t" + std::to_string(mass_flow_rate)
+ "\t" + std::to_string(setpoint);}
};当执行最顶层的代码时,第一个引用,data->pressure将正确返回,那么该地址上的所有内容都会变成垃圾,并且在这个第一个引用之后返回的数据(即data->temperature等)是不正确的。
我可以通过执行以下操作来解决这个问题
alicat_data data_ = *data;但不愿意这么做。我做了什么错事,造成了我所看到的问题?
发布于 2017-04-12 23:25:59
get_data(),您将获得指向alicat_data内存块的指针,并将其存储到可变的alicat_data *data中,即指针。alicat_data data_ = *data;,您将获得实例的内存块,因此可以使用点'.‘来访问它的方法和属性。您可以删除变量alicat_data data_ = *data;并使用变量alicat_data *data,如下所示:
for (auto const &ent : alicat_map){
alicat_data *data = (alicat_data*)ent.second->get_data();
if(ent.first == "AlicatA"){
ui->ac0_P->setValue(data->pressure);
ui->ac0_T->setValue(data->temperature);
ui->ac0_Q->setValue(data->flow_rate);
ui->ac0_Q0->setValue(data->mass_flow_rate);
ui->ac0_Qsp->setValue(data->setpoint);
}
}更新:检查此链接以检查指针理论http://www.cplusplus.com/doc/tutorial/pointers/
我还和你们中的一些人做了一个节目,向你们展示两种方法,你们的和我的:
#include <iostream>
#include <map>
using namespace std;
struct alicat_data {
float pressure; /** Pressure in mb */
float temperature; /** Temperature in degC */
float flow_rate; /** Volumetric low rate; units are defined by the model */
float mass_flow_rate; /** Mass flow rate; units are defined by the model */
float setpoint; /** Device setpoint (if it is a controller); units are defined by the model */
alicat_data(float p = 0, float T = 0, float Q = 0,
float Q0 = 0, float sp = 0) {
pressure = p;
temperature = T;
flow_rate = Q;
mass_flow_rate = Q0;
setpoint = sp;
}
virtual std::string serialize2ascii() {
return "dummy";
}
};
int main()
{
map<string, alicat_data *> alicat_map;
map<string, alicat_data *>::iterator entM;
alicat_map["AlicatA"] = new alicat_data(1.1,2.2,3.3,4.4,5.5);
alicat_map["AlicatB"] = new alicat_data(12.1, 23.2, 34.3, 45.4, 56.5);
//Your Way
for (auto const &ent : alicat_map) {
alicat_data *data = (alicat_data*)ent.second; //Get the alicat_data* (pointer) element
if (ent.first == "AlicatA") {
alicat_data data_ = *data;
float pressure = data_.pressure;
float temp = data_.temperature;
float rate = data_.flow_rate;
float mflowrate = data_.mass_flow_rate;
float setpoint = data_.setpoint;
}
}
//My Way
for (entM = alicat_map.begin(); entM != alicat_map.end(); entM++)
{
alicat_data *data = entM->second; //Get the alicat_data* (pointer) element
if (entM->first == "AlicatA") {
float pressure = data->pressure;
float temp = data->temperature;
float rate = data->flow_rate;
float mflowrate = data->mass_flow_rate;
float setpoint = data->setpoint;
}
}
return 0;
}Apirl 13的升级
我在检查你的分类alicat的代码时发现了它:
Data *alicat::get_data(){
alicat_data* ac_data = new alicat_data(0, 0, 0, 0, 0, Air);
alicat_data addr_data = parse_data(port->async_rw(string(1, address)));
ac_data = &addr_data;
return (Data*) ac_data;
}我注意到您正在返回局部变量ac_data = &addr_data;的地址,该地址将在方法Data *alicat::get_data()完成后删除。这就是在调用getData之后处理数据的原因。
要修复,您必须避免返回局部变量,因为它们在程序脱离上下文后被销毁,。返回以前由操作符new保留的实例。当物体被摧毁时,你就有了你描述的症状。
我注意到,在方法alicat_data alicat::parse_data(const std::string &msg)中也存在同样的问题。
更新:如下所示:
我不知道为什么会有这种行为,但我知道局部变量ac_data是在getData上下文结束后删除的,但是分配给parse_data的内存仍然存在,当您返回局部变量的地址时,它释放的内存(是分配到堆栈中的内存块,而不是堆),这可能是看到垃圾的原因,但是当使用alicat_data data_ = *data;时,您正在拯救分配给parse_data的内存块.怎么会!?这是一个很好的问题,它可能取决于编译器,但您可以通过何种方式来证明它是调试的,并且要小心您要进入的每个内存地址:
parse_data的内存地址getData返回到parse_data`的指针的地址。alicat_data addr_data设置为getData的内存地址。从alicat_data addr_data返回的局部变量getData的指针地址。getData后,比较指针alicat_data *data的地址与parse_data中指针的地址,并比较地址。https://stackoverflow.com/questions/43376347
复制相似问题