2017-08-08 2 views
1

Je souhaite rediriger la sortie de std::cerr et std::cout vers des fichiers. Pour ce faire, j'ai utilisé les fonctions rdbuf comme dans l'exemple de code ci-dessous. Malheureusement, je reçois l'exceptionException de violation d'accès lors de la tentative de redirection de std :: cerr vers le fichier

Exception thrown: read access violation. 

*(__imp_std::basic_ios<char,std::char_traits<char> >::rdbuf(...)) was 0xCCCCCCCC. 

chaque fois que je tente d'écrire quoi que ce soit à std::cout ou std::cerr.

Voici un exemple de code qui produit mon problème:

void redirect() 
{ 
    auto t = std::time(nullptr); 
    auto tm = *std::localtime(&t); 

    std::ostringstream oss; 
    oss << std::put_time(&tm, "%Y-%m-%d_%H-%M-%S.log"); 
    auto cerrFileName = "cerr-" + oss.str(); 
    auto coutFileName = "cout-" + oss.str(); 


    std::ofstream cerrFile(cerrFileName, std::ios::ate); // file is created 
    std::cerr.rdbuf(cerrFile.rdbuf()); 

    std::ofstream coutFile(coutFileName, std::ios::ate); // file is created 
    std::cout.rdbuf(coutFile.rdbuf()); 
} 

int main() 
{ 
    redirect(); 

    std::cout << "Test"; // The exception is thrown here. 

    return 0; 
} 

Cet exemple crée deux fichiers comme il se doit, mais ne pas écrire quoi que ce soit dans aucun d'eux. Qu'est-ce que je fais mal?

+1

Considérez la durée de vie des objets vers lesquels vous redirigez la sortie. – molbdnilo

Répondre

3

std::ofstream possèdent son tampon et quand std::ofstream objets hors de portée, ils détruisent les tampons, ce qui std::cout et std::cerr en utilisant des pointeurs non valides aux tampons.

Assurez-vous que les tampons ne sont pas supprimés prématurément.

+0

Erreur de débutant. Merci pour l'aide. – MxNx

+1

@MxNx Les erreurs sont la seule voie vers l'expertise! –

2

Avec par ex.

std::cout.rdbuf(coutFile.rdbuf()); 

vous faire std::coutparts le même tampon que coutFile, vous définissez uniquement le pointeur .

Malheureusement, std::basic_streambuf n'est pas comptabilisé. Cela signifie que lorsque la fonction redirect retourne, coutFile est détruit et fermé, ce qui inclut la destruction de l'objet tampon.

Cela laisse par ex. std::cout avec un pointeur parasite vers un objet tampon non existant.

Les flux auxquels vous partagez les objets de mémoire tampon doivent avoir une durée de vie supérieure à celle du programme complet. Et avant de quitter le programme, vous devez restaurer les tampons d'origine pour std::cout et std::cerr (rdbuf renvoie des pointeurs vers les anciens tampons).

+0

Cela a résolu le problème. Merci pour votre réponse informative. – MxNx