Frage zum FAQ Beitrag "Dateien+Verzeichnisse - FileCopy mit SHFILEOPSTRUCT"



  • Hallo,

    ich habe den Universalcode von Happy Builder im folgenden Thread ausprobiert:
    http://www.c-plusplus.net/forum/viewtopic.php?t=39283

    Es hat auch alles ganz toll geklappt!

    Mit ist allerdings aufgefallen, dass der Code auch kürzer gehalten weden könnte.

    void __fastcall FileTimeTools::ExecuteOp(AnsiString From , AnsiString  Dest, int IdOp)
    {
      TSHFileOpStruct *ShFile = new TSHFileOpStruct();
    
      From = ExpandFileName(From);
      Dest = ExpandFileName(Dest);
    
      ShFile->hwnd   = GetActiveWindow();
      ShFile->wFunc = IdOp;
      ShFile->pFrom = From.c_str();
      ShFile->pTo   = Dest.c_str();
    
      if (IdOp != FO_DELETE)
        ShFile->fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR;
      else
        ShFile->fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION;
    
     bool result = SHFileOperation(ShFile);
       ShFile->fAnyOperationsAborted;
     delete ShFile;
      }
    

    Das spart diesen Code:

    char zFrom[MAX_PATH]; 
      char zDest[MAX_PATH]; 
    
      for(int i=0; i<MAX_PATH; ++i ) 
      { 
        zFrom[i] = '\0'; 
        zDest[i] = '\0'; 
      } 
    
      strcpy(zFrom, From.c_str()); 
      strcpy(zDest, Dest.c_str());
    

    alles was man machen muss ist Dest und From mit der Methode c_str() aufzurufen

    ShFile->pFrom = From.c_str();
      ShFile->pTo   = Dest.c_str();
    

    Ich habe das ausprobiert und es funzt bei mir auch soweit.

    Jetzt meine Frage:
    Gibt es irgenteinen Grund der gegen meine Vorgehensweise spricht?

    Danke!



  • Clip schrieb:

    Gibt es irgenteinen Grund der gegen meine Vorgehensweise spricht?

    Jau. Beachte den hinwes in der FAQ zum thema .c_str(). Vor Allem was die Gültigkeit betrifft.

    Allerdings könnte man die Schleife die Happy Builder da geschrieben hat durch memset() ersetzen. Da hast du recht.

    -junix



  • Aber bei dieser Parameterübergabe

    (AnsiString From , AnsiString  Dest, int IdOp)
    

    wird doch keine Referenz, sondern eine Kopie der Strings From und Dest übergeben.

    Daher sollten sie innerhalb der Funktion doch gültig sein.
    Oder sehe ich das jetzt total falsch???

    Habe in den FAQs nichts gefunden und daher die Suchfunktion auf das Thema angesetzt.



  • Das Problem ist, dass c_str() einen Zeiger auf einen internen Puffer zurückgibt. Dieser Puffer kann sich - hast du pech - jederzeit ändern und damit wird dann auch der Zeiger ungültig. Das ist das Problem. Dies wird auch von Jansen so angedeutet.

    -junix



  • Aber im Original Code von Happy Builder wird doch an dieser stelle

    char zFrom[MAX_PATH];  
      char zDest[MAX_PATH];  
    
      for(int i=0; i<MAX_PATH; ++i )  
      {  
        zFrom[i] = '\0';  
        zDest[i] = '\0';  
      }  
    
      strcpy(zFrom, From.c_str());  
      strcpy(zDest, Dest.c_str());
    

    auch nichts anderes als ein mit c_str() zurückgegebener Wert mittels stycpy() kopiert.

    Heißt das das beide Lösungen nicht optimal sind, oder gibt es an Happy Builders Lösung etwas was dafür sorgt das das c_str() Problem nicht auftauchen kann? 😕
    (wenn dann sehe ich es nicht 😞 )

    Mir geht es nicht darum recht haben zu wollen, ich wills nur wissen 🙂



  • Deine Lösung ist weniger optimal als Happy Builders. Während des Kopiervorgangs kann eigentlich nix geschehen. Nach dem Kopiervorgang übergibt er einen bombensicheren zeiger auf den String. Bei dir kann sich der String auch im weiteren Verlauf noch ändern, da du nur den Zeiger auf den Klasseninternen String übergeben hast.

    -junix



  • Achso, ich glaub jetzt hab ichs gecheckt.

    Mein lösung ist nicht gut, da ich in ShFile die Adresse der Strings die ich durch c_str() ermittelt habe übergebe, und diese flüchtig sind.
    Wenn das so stimmt hab ichs gecheckt!

    Mach ich gleich ma alles rückgängig!

    thx!!


Anmelden zum Antworten