Definition globaler Variable in if Bedingung



  • Hallo,

    Ich sitze hier grade als ziemlicher Anfänger vor einem Problem, welches ich gerne "schön" lösen würde. Schön bedeutet für mich möglichst geringer Ressourcenverbrauch.

    Ich arbeite an einem Projekt, in welchem ich die Proteinfaltung (vereinfacht) für ein oder 2 Moleküle simuliere. Nun habe ich bereits ein funktionstüchtiges Programm für ein Protein und möchte dieses gerne um die Möglichkeit der Darstellung zweier Protein Ketten erweitern.
    Dabei sollen sämtliche für die zweite Kette benötigten Variablen nur initialisiert werden, wenn der Benutzer ausgewählt hat 2 Ketten zu berechnen. Bislang habe ich sie also einfach in einer if Bedingung Definiert:
    Beispiel:

    if (i_no_chains==2){register vector <double> v_x2_position = f_start_x2_position (D,v_gamma2,d_d);}
    

    Aus offensichtlichen Gründen klappt dies nicht, da der Compiler die Varriable bei Verlassen der if-Bedingung wieder vergisst.
    Frage:
    Lässt sich die Existenz der Variablen direkt in den if Bedingungen so erstellen, dass sie bestehen bleiben, oder hilft es nichts und ich muss die Variablen außerhalb der if-Bedingung definieren? Der Übersichtlichkeit halber wäre mir die erste Lösung lieber.
    PS: Ist register überhaupt noch sinnvoll heutzutage?



  • Du könntest sie auf den Heap parken oder die Variable vorher schon auf dem Stack packen. Statt

    if (i_no_chains==2)
    {
      register vector <double> v_x2_position = f_start_x2_position (D,v_gamma2,d_d);
    }
    

    auf den Stack per

    vector <double> v_x2_position;
    if (i_no_chains==2)
    {
      v_x2_position = f_start_x2_position (D,v_gamma2,d_d);
    }
    

    oder auf dem Heap per

    vector <double> *v_x2_position = 0L;
    if (i_no_chains==2)
    {
      v_x2_position = new f_start_x2_position (D,v_gamma2,d_d);
    }
    // Tuwas
    delete v_x2_position;
    

    Oder habe ich dich falsch verstanden?

    Gruß Kimmi



  • Hm das mit dem Heap sieht gut aus. 0L bedeutet Länge 0?

    Die Stack-Lösung ist mir auch bewusst, nur finde ich das irgendwie unübersichtlich. Hier definiert, dann aber nur eventuell wirklich benutzt ich denke ich werde mal ein wenig in dem Bereich Heap in den Tutorien lesen.

    Meine Lieblingslösung wäre eben sowas wie

    if (i_no_chains==2)
    {
      XYZ register vector <double> v_x2_position = f_start_x2_position (D,v_gamma2,d_d);
    }
    

    wobei XYZ irgend eine Anweisung sei die dem Compiler sagen soll, dass er diese Variable nicht vergessen mag.

    Vielen Dank schonmal.

    Sollte noch jemand Ideen haben, so haltet euch nicht zurück.



  • Ich bin mir nicht sicher, aber will die Frage einfach mal weitergeben, ob es denn sinnvoll ist, einen std:vector in ein Register packen zu wollen...

    Auch hab ich gerad mal fix in der MSDN geguckt - aber habs nur überflogen...

    MSDN schrieb:

    The compiler does not accept user requests for register variables.

    Wenn du die Heap-Lsg nicht magst, dann mach halt so was:

    std::vector <double> GetVector (/*parameter*/)
    { //wenn du willst, kannste da auch noch nen Template draus machen, aber ist auch egal...
    if (ich_solls_so_machen)
      return std::vector <double> (/*parameter*/);
    else if (ich_machs_einfach_so)
      return std::vector <double> (/*andere parameter*/);
    else
      return std::vector <double> (0);
    }
    
    int main ()
    {
    std::vector <double> position (GetVector (/*parameter*/));
    }
    

    der Nachteil daran ist, dass es kopiert werden muss,
    (1x richtig erstellt, 2x kopiert)
    aber das sollte
    1. nicht so ins Gewicht fallen
    2. eh nicht dein Flaschenhals sein
    3. eh egal sein
    und 4. wird es so und so rausoptimiert werden

    bb

    PS:
    kannst es auch so machen:
    (1x def-ctor erstellt, 1x richtig erstellt, 1x kopiert)

    void GetVector (std::vector <double> &vector, /*andere parameter*/)
    { //kannst auch wieder nen template draus machen, wenn du willst...
    vector = std::vector <double> (/*bla*/);
    }
    
    int main ()
    {
    std::vector <double> vec;
    GetVec (vec, /*rest*/);
    }
    


  • Das Schlüsselwort register ist sowieso nur eine Empfehlung an den Compiler, es kann also sehr gut sein, dass nichts in Registern abgelegt wird (vor allem kein ganzer Vector in einem ;)). Man sollte es nur bei sehr häufig gebrauchten Variablen verwenden, wenn man sehr zeitkritisch arbeitet. Und dann sorgfältig mit Profiler und Zeitmessungen überprüfen, ob es sich überhaupt lohnt.

    Eine Möglichkeit zu deinem Problem ist static . Wenn du etwas statisch definierst, ist es bis zum Programmende gültig - aber nur in dem Gültigkeitsbereich, wo es deklariert wurde. Um es ausserhalb bekannt zu machen, könntest du einen Zeiger verwenden. In deinem Fall würde ich aber eher davon abraten, da der Vektor ja auch ausserhalb benötigt wird.

    Aber ich würde mir auch überlegen, den Vector ausserhalb des If-Blockes zu deklarieren, dass er auch nachher noch existiert. Dann wird er auch ordentlich zerstört, wenn er den aktuellen Block verlässt, und nicht erst am Ende des Programms.

    Tembudrus schrieb:

    Die Stack-Lösung ist mir auch bewusst, nur finde ich das irgendwie unübersichtlich.

    Das würde ich nicht sagen. Heap bedeutet immer mehr Verantwortung und mehr Fehlerquellen. Spätestens wenn du immer Probleme mit Zeigern/Heap Corruptions/Memory Leaks hast, wirst du es auch nicht mehr übersichtlicher finden.

    Du solltest, sofern möglich, Stackvariablen benutzen. Der Vorteil ist, dass dir die Arbeit der Speicherverwaltung abgenommen wird. Das Allokieren auf dem Heap braucht auch mehr Zeit, und bei Stackvariablen entfällt auch die Zeigerdereferenzierungssyntax (zum Thema Übersichtlichkeit).

    Tembudrus schrieb:

    0L bedeutet Länge 0?

    Das Literal 0L oder 0l ist ein long int mit dem Wert 0. Das angehängte "l" deutet auf den long -Typen hin (wie z.B. "f" bei float ).



  • 0L oder auch NULL benutzte ich da oben, um den Pointer zu initialisieren. Damit will ich zeigen, daß der Pointer noch nicht benutzt wird -> ergo 0L.

    Gruß Kimmi



  • 0L für nen Pointer is unfug, 0 reicht vollkommen.


Anmelden zum Antworten