Speicherzugriffsfehler



  • Erstmal sorry für den langen Code aber es geht leider nicht anders...

    Also, folgende Funktion wird in einer Endlosschleife aufgerufen:

    int Netzwerk::get_online()
    {
        int online = 0;
        int angeschlossen = 0;
        int len;
        char ausgabe[501];
        for(int i=1; i < 254; ++i)
        {
    	char hostname[120];
    	char command[120];	
    	sprintf(hostname, "%s%d", netz, i);
    	sprintf(command, "nslookup %s", hostname);
    	FILE *ping = popen(command, "r");
    	len = fread(ausgabe, 1, 500, ping);
    	assert (len <= 500);
    	assert (len >= 0);
    	cout << "i: " << i << " Es wurden " << len << " Zeichen gelesen!" << endl;
    	ausgabe[len]=0;
    	cout << ausgabe << endl;
    	int dummy = 1;
    	char *token;
    	token = strtok(ausgabe, " "); // Dasselbe wie bei get_angeschlossen!
    	int tok_n = 1;
    	while(token = strtok(0, " "))
    	{
    	    ++tok_n;
    	}
    	if(tok_n == 3) // Alle angeschlossenen Computer werden angepingt
    	{
    	    ++angeschlossen;
    	    char command[120];	
    	    sprintf(command, "ping -c 1 -W 10 %s", hostname);
    	    FILE *ping = popen(command, "r");
    	    char ausgabe[501];
    	    int len = fread(ausgabe, 1, 500, ping);  // FEHLER
    	    assert (len <= 500);
    	    assert (len >= 0);
    	    cout << "i: " << i << " Es wurden " << len << " Zeichen gelesen!" << endl;
    	ausgabe[len]=0;
    	cout << ausgabe << endl;
    	    int dummy = 1;
    	    char *token;
    	    token = strtok(ausgabe, " ");
    	    int tok_n = 1;
    	    while(token = strtok(0, " "))
    	    {
    		++tok_n;
    	    }
    	    if(tok_n == 31)
    	    {
    		printf("\n%s ist online!\n", hostname);
    		++online;
    	    }
    	}
        }
        cout << endl << endl;
        if(angeschlossen==1) 
        {
    	cout << "Es ist 1 Computer angeschlossen!" 
    	     << endl << endl; 
        }
        else 
        {
    	cout << "Es sind " << angeschlossen 
    	     << " Computer angeschlossen!" << endl << endl;
        }
        if(online==1) 
        {
    	cout << "Es ist 1 Computer online!" 
    	     << endl << endl;
        }
        else 
        {
    	cout << "Es sind " << online << " Computer online!" 
    	     << endl << endl;
        } 
        return online;
    }
    

    3x wird die Funktion problemlos aufgerufen und gibt auch den richtigen Wert zurück, beim 4. Mal taucht jedoch bei i = 224 ein Speicherzugriffsfehler auf!
    Hier die Ausgabe von valgrind:

    [...]
    ==8071== Warning: invalid file descriptor 1019 in syscall pipe()
    ==8071== Invalid read of size 2
    ==8071==    at 0x4FE47C4: fread (in /lib64/libc-2.4.so)
    ==8071==    by 0x402547: Netzwerk::get_online() (Netzwerk.cpp:84)
    ==8071==    by 0x4015E6: main (main.cpp:20)
    ==8071==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
    ==8071==
    ==8071== Process terminating with default action of signal 11 (SIGSEGV)
    ==8071==  Access not within mapped region at address 0x0
    ==8071==    at 0x4FE47C4: fread (in /lib64/libc-2.4.so)
    ==8071==    by 0x402547: Netzwerk::get_online() (Netzwerk.cpp:84)
    ==8071==    by 0x4015E6: main (main.cpp:20)
    ==8071==
    ==8071== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 1)
    ==8071== malloc/free: in use at exit: 258,304 bytes in 1,009 blocks.
    ==8071== malloc/free: 1,028 allocs, 19 frees, 295,817 bytes allocated.
    ==8071== For counts of detected errors, rerun with: -v
    ==8071== searching for pointers to 1,009 not-freed blocks.
    ==8071== checked 4,480,416 bytes.
    ==8071==
    ==8071== LEAK SUMMARY:
    ==8071==    definitely lost: 0 bytes in 0 blocks.
    ==8071==      possibly lost: 0 bytes in 0 blocks.
    ==8071==    still reachable: 258,304 bytes in 1,009 blocks.
    ==8071==         suppressed: 0 bytes in 0 blocks.
    ==8071== Reachable blocks (those to which a pointer was found) are not shown.
    ==8071== To see them, rerun with: --show-reachable=yes
    Speicherzugriffsfehler
    

    (Die Zeile ist mit //FEHLER markiert!)

    Hat jemand eine Idee an was es liegen kann? Ich bin am verzweifeln 😞

    Hat jemand eine Alternative für die markierte Zeile? Am besten fände ich, wenn die Ausgabe der shell direkt in einen <string>-string übergeben wird!



  • 1. Es ist pure Dummheit bei Funktionen wie popen einfach davon auszugehen, daß sie schon funktionieren. das gehört so:

    if( FILE *ping = popen(command, "r") ) {
       // whatever
    }
    else {
       // Fehlerauswertung
    }
    

    2. Du öffnest zwar massenhaft Streams (popen) machst sie aber nie wieder zu. (pclose). Also wirst Du früher oder später einfach gegen eine Grenze rennen (ka wieiele Streams gleichzeitig maximal von einem Progrmm geöffnet werden können)

    if( FILE *ping = popen(command, "r") ) {
       // whatever
    
       pclose(ping);  // Das muss
    }
    else {
       // Fehlerauswertung
    }
    


  • schuela schrieb:

    1. Es ist pure Dummheit bei Funktionen wie popen einfach davon auszugehen, daß sie schon funktionieren. das gehört so:

    if( FILE *ping = popen(command, "r") ) {
       // whatever
    }
    else {
       // Fehlerauswertung
    }
    

    2. Du öffnest zwar massenhaft Streams (popen) machst sie aber nie wieder zu. (pclose). Also wirst Du früher oder später einfach gegen eine Grenze rennen (ka wieviele Streams gleichzeitig maximal geöffnet werden können)

    if( FILE *ping = popen(command, "r") ) {
       // whatever
    
       pclose(ping);  // Das muss
    }
    else {
       // Fehlerauswertung
    }
    


  • Oh, da zeigt sich mal wieder meine Unerfahrenheit...

    ➡ Vielen, vielen Dank!! 👍
    Funktioniert jetzt einwandfrei... 😋



  • [erledigt]


Anmelden zum Antworten