2016-11-27 1 views
1

J'ai un problème étrange où un simple cout dérange mes pointeurs précédemment définis. Voici le code:cout écrase certains de mes pointeurs

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; 
} 

Ici, je crée un objet « fermeture » avec la fonction liée (une « méthode ») qui utilise des pointeurs ne sont pas encore définis comme arguments, qui seront liés plus tard lors de l'exécution.

plus tard: (comme 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 
} 

Y at-il un problème avec la façon dont je définis au départ a et b Obtiennent-ils désallouées ou quelque chose? J'ai essayé de les rendre "statiques" mais ça ne marche pas non plus. Quelque chose ne va pas sur le niveau général :(

+1

cela ressemble à un comportement non défini me – Rakete1111

+0

double possible de [Créer un signal avec Gtkmm] (http://stackoverflow.com/questions/40822089/create-a -signal-with-gtkmm) – wasthishelpful

+0

Vous p Robably besoin d'afficher un ensemble COMPLET de code qui peut être exécuté. –

Répondre

2

La question principale est ici.

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

Ce lambda crée une fermeture qui fait référence à des variables locales Cette fermeture n'est plus appelable une fois les variables hors de portée. Je pense que vous voulez faire quelque chose comme:.

#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

Une question cependant: quand les pointeurs d'arguments sont renommés (* clos-> args [0] = a;) l'ancienne valeur allouée est garbage right? Comment supprimer cette ancienne valeur, si je ne tiens pas de référence? – artemonster

+0

Je viens de comprendre maintenant pourquoi ce n'est pas vraiment une réponse à mon problème: vous effectuez une copie de valeur pour args et je veux les passer par référence :) – artemonster

+0

@artemonster: Voici une autre approche: http: //coliru.stacked- crooked.com/a/8e7adc1aad4a559c –