2016-11-27 8 views
1

간단한 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* 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; 
} 

I 런타임에 나중에 결합 될 인수로서 있지 아직 정의 된 포인터를 사용하여 결합 함수 (a "방법")와 오브젝트 "폐쇄"를 생성한다.

나중에 : (? nullpointers로)

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 
} 

내가 처음 정의와 b 방법에 문제가있는 그들이 할당 취소 또는 뭔가받을 수 있나요? 나는 그것들을 "정적"으로 만들려고했지만 그것도 작동하지 않는다. .이 람다는 지역 변수를 참조하는 폐쇄를 만드는

closure->method = [&a, &b, &out](){out->val = a->val + b->val;}; 

변수가 범위 밖으로 이동하면이 폐쇄가 더 이상 호출 할 수 없습니다 : 주요 문제는 여기에있다 :(

+1

이 정의되지 않은 동작처럼 보이는을의 – Rakete1111

+0

가능한 중복 (http://stackoverflow.com/questions/40822089/create-a [Gtkmm와 신호를 만들기] -signal-with-gtkmm) – wasthishelpful

+0

You p 로봇을 실행할 수있는 완벽한 코드 세트를 게시해야합니다. –

답변

2

뭔가 일반적인 수준에 대한 잘못된 것입니다. 난 당신이 더 같은 것을 할 생각한다. 나에게

#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; 
} 
+0

한 가지 질문 : args 포인터의 이름이 바뀌면 (* clos-> args [0] = a;) 오래된 할당 값은 가비지입니다. 내가 그 참조를 가지고 있지 않다면 그 옛 값을 지우는 법? – artemonster

+0

방금 ​​왜 이것이 내 문제에 대한 답이 아님을 이해했습니다. args에 대한 값 복사본을 수행하고 참조로 전달하려고합니다. – artemonster

+0

@artemonster : 여기에 또 다른 방법이 있습니다. http : //coliru.stacked- crooked.com/a/8e7adc1aad4a559c –