C++ cout覆盖了我的一些指针

C++ cout覆盖了我的一些指针,c++,pointers,lambda,runtime-error,cout,C++,Pointers,Lambda,Runtime Error,Cout,我有一个奇怪的问题,一个简单的cout会把我先前定义的指针弄乱。代码如下: union Value { bool a; long long val; int next; }; struct Clos { //not a "closure" in its actual sense. vector<Value**> args; function<void()> method; }; Clos* prepare() { Clos*

我有一个奇怪的问题,一个简单的cout会把我先前定义的指针弄乱。代码如下:

union Value {
    bool a;
    long long val;
    int next;
};

struct Clos { //not a "closure" in its actual sense.
    vector<Value**> args;
    function<void()> method;
};

Clos* prepare() {
  Clos* closure = new Clos();

  Value* a = nullptr; //these values do not exist yet, but I need these pointers to rename them at RT
  Value* b = nullptr;
  Value* out = new Value; //this exists
  closure->args.push_back(&a); //save adresses to rename them later
  closure->args.push_back(&b);
  closure->method = [&a, &b, &out](){out->val = a->val + b->val;}; //just some operation on arguments
  return closure;
}
联合值{
布尔a;
长瓦尔;
int-next;
};
struct Clos{//不是实际意义上的“闭包”。
向量args;
函数法;
};
Clos*prepare(){
Clos*close=新Clos();
Value*a=nullptr;//这些值还不存在,但我需要这些指针在RT时重命名它们
值*b=nullptr;
Value*out=新值;//此值存在
closure->args.push_back(&a);//保存地址以便稍后重命名
关闭->参数推回(&b);
闭包->方法=[&a,&b,&out](){out->val=a->val+b->val;};//只是对参数进行一些操作
返回关闭;
}
在这里,我使用绑定函数(“方法”)创建一个对象“closure”,它使用尚未定义的指针作为参数,稍后将在运行时绑定

后来:

 int main(void) {
  Clos* clos = prepare();
  Value a; //now we get input values at RT
  a.val = 7;
  Value b;
  b.val = 8;
  *clos->args[0] = &a; //we bind them to previously "dangling" pointers
  *clos->args[1] = &b;
  cout << "WOLOLOLOLO"; //<<<<---- COMMENT OUT THIS LINE AND BOOM!
  clos->method(); //this works, as long cout is not called 
}
int main(无效){
Clos*Clos=prepare();
值a;//现在我们在RT处获得输入值
a、 val=7;
b值;
b、 val=8;
*clos->args[0]=&a;//我们将它们绑定到以前的“悬空”指针
*clos->args[1]=&b;

cout主要问题是:

closure->method = [&a, &b, &out](){out->val = a->val + b->val;};
此lambda正在创建一个引用局部变量的闭包。一旦变量超出范围,此闭包将不再可调用。我认为您需要类似以下内容:

#include <vector>
#include <iostream>
#include <functional>

using std::vector;
using std::function;
using std::cout;


union Value {
  bool a;
  long long val;
  int next;
};

struct Clos { //not a "closure" in its actual sense.
  vector<Value*> args;
  function<void()> method;

  ~Clos()
  {
    for (auto &arg : args) {
      delete arg;
    }
  }
};

Clos* prepare() {
  Clos* closure = new Clos();

  Value* a = new Value;
  Value* b = new Value;
  Value* out = new Value; //this exists
  closure->args.push_back(a);
  closure->args.push_back(b);
  closure->args.push_back(out);

  // Make copies of the pointers, not references.
  closure->method = [a, b, out](){out->val = a->val + b->val;};

  return closure;
}

int main(void) {
  Clos* clos = prepare();
  Value a; a.val = 7;
  Value b; b.val = 8;
  *clos->args[0] = a;
  *clos->args[1] = b;
  clos->method();
  cout << clos->args[2]->val << "\n";

  delete clos;
}
#包括
#包括
#包括
使用std::vector;
使用std::函数;
使用std::cout;
联合价值{
布尔a;
长瓦尔;
int-next;
};
struct Clos{//不是实际意义上的“闭包”。
向量args;
函数法;
~Clos()
{
用于(自动参数:参数(&A){
删除arg;
}
}
};
Clos*prepare(){
Clos*close=新Clos();
值*a=新值;
值*b=新值;
Value*out=新值;//此值存在
关闭->参数。推回(a);
关闭->参数向后推(b);
关闭->args.向后推(出);
//复制指针,而不是引用。
闭包->方法=[a,b,out](){out->val=a->val+b->val;};
返回关闭;
}
内部主(空){
Clos*Clos=prepare();
值a;a.val=7;
值b;b.val=8;
*clos->args[0]=a;
*clos->args[1]=b;
clos->method();

cout args[2]->val这在我看来似乎是未定义的行为。您可能需要发布一整套可以运行的代码。似乎您对闭包的工作方式有误解。您的
closure->args
的意义是什么?您是否试图使它成为可以更改
a
b
的内部含义的地方
eval
?@这有帮助吗?不,我在那里找不到答案。但有一个问题:当args指针重命名(*clos->args[0]=a;)旧的分配值是垃圾,对吗?如果我没有对它进行引用,如何删除旧值?我刚刚理解了为什么这实际上不是我问题的答案:您对args执行值复制,我希望通过引用传递它们:)@artemonster:还有另一种方法: