如何解决返回后的结构成员地址
以下代码模拟了我正在使用的一些代码。基本上query = "SELECT 1 a,2 b,'a' c UNION ALL SELECT 7,4,'snow'"
cur = connection.cursor()
df = cur.execute(query).fetch_pandas_all()
df.to_csv('x.csv',index = False)
会分配一个struct Foo
成员(std::vector
),然后将其他一些成员定义为指向向量内容的指针(d_vec
)。
d_buf
现在,以下内容对我来说很好:
#include <cstddef>
#include <vector>
struct Foo
{
Foo(std::size_t n)
: d_vec(n,0.),d_buf(d_vec.data())
{}
std::vector<double> d_vec;
double* d_buf;
};
我不确定这是什么
void buildAndUseFoo()
{
Foo f{10};
// do stuff with f.d_buf,it is safe
// ...
}
我想知道Foo buildAndReturnFoo()
{
Foo f{10};
return f;
}
void someMethod()
{
auto f = buildAndReturnFoo();
// is it safe to use f.d_buf?
// ...
}
的地址是否可以从在d_vec
中创建时的地址更改为在buildAndReturnFoo()
中使用时的地址。然后,如果尝试取消引用它,则会得到未定义的行为。
注意:我已经测试过打印地址,并且碰巧它们是相同的,但是我想确保可以保证,而且我不依赖“运气”。
注2:我知道更安全的方法;我只是想了解这种情况。
解决方法
在任何情况下复制或移动您的结构都是危险的,不仅限于函数返回。
当复制/移动这样的结构时,目标对象的d_buf
仍指向原始向量的数据。几乎可以肯定这不是您想要的。因此,您需要尊重5 [*]规则的精神,并实现一个都做正确的事情的复制ctor,复制赋值运算符,移动ctor和移动赋值运算符,即更新d_buf
指向的位置。或通过delete
设置这些功能来禁用复制和/或移动。
另一种方法是摆脱d_buf
。将其替换为成员函数buffer()
,该成员函数可即时访问引导程序的data()
。因为获取该指针是一项廉价的操作,所以我倾向于此解决方案。
[*] rule of 5指出,如果您需要实现复制ctor,复制赋值,移动ctor,移动赋值或析构函数中的至少一项,则需要全部五个。您的结构体不会显式管理任何资源,因此您不需要析构函数,并且从技术上讲,它不是完整的5规则。但是其精神仍然适用。
,观察到的行为可能是由以下原因引起的:
- 如果通过将数据传输到新
vector
来构建filterOption={(input,option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0 }
,则C ++ 11 move语义 - C ++ 17复制/移动操作(又名RVO / NRVO)的省略
出于第一个原因,极有可能发生不重新分配而传输数据的情况,但该标准并未对此强制执行。
由于第二个原因,即使在C ++ 17之前,它也很有可能发生,但是它被命名为变量,因此不属于 复制/移动操作的强制性省略。
因此,在实践中观察到的行为很有可能,但不能保证。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。