2016-05-06 20 views
-1

ich zu Debug-Code versucht, die schließlichDebug glibc free(): ungültiger Zeiger

*** glibc detected *** ./build/smonitor: free(): invalid pointer: 

Seine Herausforderung, weil ich die anderen frei ... Ich habe gesehen, wirft nicht verwenden SO Beiträge, die haben Beispiele, die das Problem replizieren. Ich brauche Hilfe beim Debuggen. Zunächst einmal bin ich ein C/C++ n00b, also sind meine Pointer-Fähigkeiten in Entwicklung, aber ich mache nicht viel dynamische Speicherzuweisung (denke ich).

Ich fange an, meine eigene "Sicherheits" -Anwendung zu schreiben, wo ich Schnappschüsse von Kameras mache und sie auf eine NFS-Freigabe schreibe, werde ich schließlich eine Anzeige des Schnappschusses jeder Kamera haben. Momentan nehme ich Captures von 1 Kamera und fahre sie durch mein Anzeigefenster (mit opencv). Ich kann eine Weile laufen (~ Stunde), bevor ich den Core Dump bekomme. Ich erstelle einen Thread, um das Fenster zu laufen, ich sollte Schleife, bis mein Laufflag auf false gesetzt wird und dann rufe ich cvReleaseImage auf. Ich habe keine Ahnung, warum dies fehlschlägt, jede Anleitung wird sehr geschätzt!

// will be replaced with camera X filename on NFS share 
std::string generate_filename() 
{ 
    static const char alphanum[] = 
       "" 
       "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
       "abcdefghijklmnopqrstuvwxyz"; 

    std::string filename = ""; 
    std::stringstream ss; 
    for (int i = 0; i < 10; i++) 
    { 
     ss << alphanum[rand() % (sizeof(alphanum) - 1)]; 
    } 
    ss << ".jpg"; 
    printf("Generated filename: %s\n", ss.str().c_str()); 
    return ss.str(); 
} 

std::string generate_file_path() 
{ 
    std::stringstream ss; 

    ss << CAPTURES_PATH << generate_filename(); 
    return ss.str(); 
} 


void capture_photo(std::string& filepath) 
{ 
    time_t now; 
    time_t end; 
    double seconds; 
    bool cancelCapture = false; 
    int count = 0; 

    CvCapture* capture = cvCreateCameraCapture(0); 
    printf(“Opened camera capture\n"); 
    IplImage* frame; 
    while(1) 
    { 
     frame = cvQueryFrame(capture); 
     if (!frame) 
     { 
      fprintf(stderr, "Could not read frame from video stream\n\n"); 
     } else 
     { 
      cvShowImage(WINDOW, frame); 
      cvWaitKey(100); 
      if (get_snapshot_enabled()) // simulate delay between snapshots 
      { 
       filepath = generate_file_path(); 
       printf("Saving image\n"); 
       cvSaveImage(filepath.c_str(), frame); 
       break; 
      } 
     } 
    } 
    printf("Ending camera capture\n"); 
    cvReleaseCapture(&capture); 
} 

void* manage_window(void* arg) 
{ 
    time_t now; 
    time_t end; 
    double seconds = 0; 
    double stateSec; 

    int i = 0; 
    int rem = 0; 

    IplImage* images[10]; 

    time_t lastUpdate; 
    time_t tDiff; // time diff 

    cvNamedWindow(WINDOW, CV_WINDOW_FREERATIO); 
    cvSetWindowProperty(WINDOW, CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN); 

    std::string filepath; 
    time(&now); 
    int lastPos = 0; 
    while (1) 
    { 
     if (get_snapshot_enabled()) 
     { 
      write_console_log("Going to capture photo\n"); 
      // camera was selected 
      filepath = generate_file_path(); 
      printf("Generated filepath: %s\n", filepath.c_str()); 
      capture_photo(filepath); 

      if (!filepath.empty()) 
      { 
       printf("Received filepath: %s\n", filepath.c_str()); 
       time(&now); 

       images[lastPos] = cvLoadImage(filepath.c_str()); 
       cvShowImage(WINDOW, images[lastPos]); 
       cvWaitKey(100); 
       if (lastPos == 10) lastPos = 0; 
       else lastPos++; 
      } 
     } 

     time(&end); 
     seconds = difftime(end, now); 
     if (seconds >= 5) 
     { 
      cvShowImage(WINDOW, images[ i % 10]) 
      cvWaitKey(100); 

      i++; 
      time(&now); 
     } 

     // check if we're running 
     if (!get_running()) 
     { 
      // log some error we're not running... 
      write_logs("Window thread exiting, not running..."); 
      break; 
     } 
    } 

    for (i=0; i < 10; i++) 
     cvReleaseImage(&images[i]); 

    pthread_exit(NULL); 
} 
+2

Markieren Sie nicht "C", wenn Sie 'C++' verwenden. – PaulMcKenzie

+2

Haben Sie Ihr Programm unter dem Debugger Ihrer Entwicklungsumgebung ausgeführt? Sollte Ihnen helfen, einzugrenzen, wo das schlechte "freie" auftritt. – user4581301

+3

Das 'if (lastPos == 10) lastPos = 0; else lastPos ++ 'scheint zu' images [10] = ... 'zu führen, d.h. ungültiges Schreiben über das Ende des Arrays hinaus. –

Antwort

1

In void* manage_window(void* arg) gibt es Linien

IplImage* images[10]; 

und

images[lastPos] = cvLoadImage(filepath.c_str()); 

if (lastPos == 10) lastPos = 0; 
else lastPos++; 

wo lastPos kann auf 10 erhöht werden, um

führenden
images[10] = cvLoadImage(filepath.c_str()); 

d.h. ungültig Schreib beyo nd das Ende des Arrays. Ich denke so etwas wie valgrind hätte dies erkannt.

+0

Bevor Sie Valgrind ausprobieren, versuchen Sie [Address Sanitizer] (http://clang.llvm.org/docs/AddressSanitizer.html). Es läuft viel schneller und fängt die meisten der gleichen Fehler. Natürlich ist Valgrind der Goldstandard für solche Dinge. –