指向矢量的指针:函数中的大小正确,但在调用者中为 0
Pointer to vector: size is correct in function but 0 in caller
我有一个简单的函数,我简化了它,只返回一个虚拟列表(以确保它没有一些逻辑错误)
vector<AttrValue>* QueryEvaluator::getCandidateList(...) {
...
values.clear();
values.push_back(2);
values.push_back(3);
cout << "values is of size " << values.size() << endl;
return &values;
}
然后在 CPPUnit 测试中:
vector<AttrValue>* candidateList0 = evaluator->getCandidateList(cl, 0);
cout << candidateList0->size() << endl;
但问题是size()
,在测试中,即使cout
消息打印正确的大小 2,也始终为 0。可能出了什么问题?
我尝试了一个简单的程序,它似乎很好...
#include <iostream>
#include <vector>
using namespace std;
vector<int>* test() {
vector<int> vec { 2, 3, 6, 1, 2, 3 };
return &vec;
}
int main() {
cout << test()->size() << endl;
return 0;
}
您正在从函数返回临时地址getCandidateList
该对象,当函数返回时,对象将被释放。 访问它是未定义的行为。您可以返回向量,RVO 应该来应用并删除副本:
尝试:
std::vector<AttrValue> QueryEvaluator::getCandidateList(...)
{
//blah
return values;
}
我尝试了一个简单的程序,它似乎很好...
当 getCandidate List 函数返回时,将释放临时向量。程序具有未定义的行为。
您的向量似乎是在堆栈上声明的,因此当它超出范围时(当函数退出时)将被销毁。 如果要返回指向向量的指针,请改为将其分配给堆上
vector<AttrValue>* QueryEvaluator::getCandidateList(...) {
vector<AttrValue>* values = new vector<AttrValue>();
...
values->clear();
values->push_back(2);
values->push_back(3);
cout << "values is of size " << values->size() << endl;
return values;
}
相反,在调用方中声明它并将引用传递给getCandidateList
可能更容易
void QueryEvaluator::getCandidateList(vector<AttrValue>& values)
。或按值返回
vector<AttrValue> QueryEvaluator::getCandidateList(...) {
有很多有趣的事情需要考虑:
vector<AttrValue>* QueryEvaluator::getCandidateList(...) {
...
values.clear();
values.push_back(2);
values.push_back(3);
cout << "values is of size " << values.size() << endl;
return &values;
}
所以看起来你漏掉了上面的代码中最有趣的部分。故事的寓意是尝试提供显示错误的可编译工作代码。将问题简化为一个小例子通常会导致您自己找到问题。至少你应该提供所有使用的对象的确切定义(类型是C++中最重要的东西)
它是否将向量声明为本地对象?
std::vector<int> values;
在这种情况下,向量的生命周期绑定到函数,并在函数结束时被销毁。这意味着在函数返回后使用它是一种未定义的行为(任何事情都可能发生)。
但看起来您正在使用对象作为单元测试框架的一部分。因此,一个可能的解决方案是使矢量成为对象的一部分。然后,只要对象(不仅仅是函数调用),向量就会存在,因此返回指向它的指针将按预期工作。
class QueryEvaluator
{
std::vector<int> values;
public:
vector<AttrValue>* QueryEvaluator::getCandidateList(...);
};
另一种方法是按值而不是指针返回向量。这意味着对象将被正确地从函数中复制出来,并且调用代码可以操作和测试所需的向量。
vector<AttrValue> QueryEvaluator::getCandidateList(...)
{
...
return &values;
}
旁注:
此外,您还需要尽量不要在代码中使用指针。指针不传达任何所有权。这意味着我们不知道谁负责删除对象。在这种情况下,引用可能会更好(您永远不会返回 NULL),因为这赋予调用方对对象的访问权限将保留所有权(假设您决定不按值返回)。
- 方法中填充的shared_ptr到map在调用者中返回为空
- 具有指向方法回调的指针的通用回调模板类
- 从函数返回的左值引用实际上是右值(从调用者的角度来看)
- 如何在C++中向epoll_event结构传递回调函数指针
- 如何在类成员函数中打印调用者对象名称
- std::thread::d etach 在原始调用者被销毁后会导致崩溃
- 将局部变量作为向量的成员传递给被调用者
- c++定时器实现-将一个成员函数分配给信号回调函数指针
- 带/不带类C++回调函数指针
- 函数调用者如何使用头文件来确定如何处理已编译的二进制文件
- 能否在c++的成员函数中找到调用者?
- 线程问题:控制权没有返回给调用者
- Boost绑定回调函数指针作为参数
- 如何在sublime text 2或3中找到c++函数的所有调用者
- c++返回相同的对象给调用者
- c++11为调用者构造对象
- 在调用者内部扩展被调用者的指导原则是什么(内联-编译器优化)
- Qt获取信号调用者并逐行读取文件
- 我如何发送cpp回调函数指针到java
- 指向矢量的指针:函数中的大小正确,但在调用者中为 0