Programm segfaults beim Beenden
Hallo Liste,
ich schreibe an einem kleineren gtk-Programm und habe da so meine
Anfangsschwierigkeiten. Beim debuggen mit gdb bin ich dem Problem
näher gekommen und habe die betreffenden Funktionen extrahiert und
in ein Progrämmchen gepackt:
#include
On Wednesday 18 February 2004 17:15, Michael Unterkalmsteiner wrote:
while ((dir = readdir(dp)) != NULL) { name = dir->d_name;
if (stat (name, &filestat) >= 0) { if (S_ISDIR (filestat.st_mode)) { di->name = g_list_prepend (di->name, name); } name = NULL; } g_free (name); ^^^^^^^^^^^^^^ Bist du des Wahnsinns fette Beute? Das gehört dir nicht, das darfst du nicht freigeben!
} closedir (dp);
CU
--
Stefan Hundhammer
On Wed, Feb 18, 2004 at 05:30:25PM +0100, Stefan Hundhammer wrote:
On Wednesday 18 February 2004 17:15, Michael Unterkalmsteiner wrote:
while ((dir = readdir(dp)) != NULL) { name = dir->d_name;
if (stat (name, &filestat) >= 0) { if (S_ISDIR (filestat.st_mode)) { di->name = g_list_prepend (di->name, name); } name = NULL; } g_free (name); ^^^^^^^^^^^^^^ Bist du des Wahnsinns fette Beute? Das gehört dir nicht, das darfst du nicht freigeben!
ACK, da hab ich wohl geschlafen, trotzdem schmiert das Programm weiterhin ab und ich hab weiterhin Tomaten auf den Augen und find den Fehler nicht.
} closedir (dp);
CU --
Mfg, Michael -- Sehr gespannt sind alle Fachleute auf die türkische Version von ŽApollo 13Ž. Ohne Tom Hanks, aber es geht um einen Granada der zwischen Antalia und Berlin liegenbleibt! -- Harald Schmidt
On Thursday 19 February 2004 14:16, Michael Unterkalmsteiner wrote:
ACK, da hab ich wohl geschlafen, trotzdem schmiert das Programm weiterhin ab und ich hab weiterhin Tomaten auf den Augen und find den Fehler nicht.
Das hängt aber wohl damit zusammen; ich weiß nicht genau, was dieses
g_list_prepend() macht, aber ich denke mal, es allokiert wohl nicht selber
nochmal Speicher für den Dateinamen - dafür mußt Du selber sorgen. Der Inhalt
von "dir", also auch "dir->name", wird irgendwann ungültig - "dir" zeigt auf
eine Struktur innerhalb von readdir(). Du merkst Dir also in dieser Liste
-zig mal die gleiche Adresse, wo aber inzwischen schon gar nichts mehr oder
irgendwas anderes steht.
-> Du mußt für den Namen selber Speicher allokieren, etwa so:
name = strdup( dir->d_name );
di->name = g_list_prepend (di->name, name);
Und freigeben wieder, wenn Du die gesamte Liste zerstörst - und erst dann.
Da lernt man die Vorzüge von C++ und anständigen String- und Containerklassen
gleich wieder richtig zu schätzen... ;-)
CU
--
Stefan Hundhammer
On Thu, Feb 19, 2004 at 03:14:16PM +0100, Stefan Hundhammer wrote:
On Thursday 19 February 2004 14:16, Michael Unterkalmsteiner wrote:
ACK, da hab ich wohl geschlafen, trotzdem schmiert das Programm weiterhin ab und ich hab weiterhin Tomaten auf den Augen und find den Fehler nicht.
Das hängt aber wohl damit zusammen; ich weiß nicht genau, was dieses g_list_prepend() macht, aber ich denke mal, es allokiert wohl nicht selber nochmal Speicher für den Dateinamen - dafür mußt Du selber sorgen. Der Inhalt von "dir", also auch "dir->name", wird irgendwann ungültig - "dir" zeigt auf eine Struktur innerhalb von readdir(). Du merkst Dir also in dieser Liste -zig mal die gleiche Adresse, wo aber inzwischen schon gar nichts mehr oder irgendwas anderes steht.
-> Du mußt für den Namen selber Speicher allokieren, etwa so:
name = strdup( dir->d_name ); di->name = g_list_prepend (di->name, name);
Und freigeben wieder, wenn Du die gesamte Liste zerstörst - und erst dann.
Sowas ähnliches hatte ich vorher auch schon gemacht (daher auch der blöde Fehler mit g_free(name), nämlich: name = g_strconcat(name, NULL); ..Moment, ich probier grad nebenbei was aus, und ich glaub ich hab den Fehler gefunden. main() sieht nun folgendermaßen aus: .. path = g_strdup (g_get_current_dir ()); di->path = path; get_dirs_in_path (di); .. g_free (di->path); g_list_free (di->name); g_free (path); ..nochmal 4 Stunden später ... hab bemerkt, dass ich für 'di' keinen Speicher allociert habe *badamm*, also di = g_new0 (Dirinfo, 1); Jetz hab ich Kopfweh ;-), danke aber für die Hilfe, hast mich auf den richtigen Weg geführt Mfg, Michael -- Man hat festgestellt, dass zwei Drittel aller Lügen innerhalb der Familie passieren! Die häufigsten Lügen in der Familie sind 1. Ž Hmmm, lecker!Ž, 2. ŽIch Dich auch!Ž und 3. ŽDas? Da hat mich Ž ne Katze gekratzt!Ž -- Harald Schmidt
Hallo, Am Wed, 18 Feb 2004, Michael Unterkalmsteiner schrieb:
gboolean get_dirs_in_path (gpointer data) { Dirinfo *di = data; DIR *dp; struct dirent *dir; struct stat filestat; gchar *name;
di->name = NULL; dp = opendir (di->path);
Du pruefst 'di' nicht, und auch 'dp' bzw. den Rueckgabewert von opendir nicht. [..]
int main (void) { Dirinfo *di; gint n;
di->path = g_get_current_dir ();
Wo hast du di allokiert? 'di' ist ein Pointer nach irgendwo! Dirinfo di; di.path = g_get_current_dir ();
get_dirs_in_path (di);
get_dirs_in_path (&di); [usw.] Oder du musst 'di' selber allokieren und dann auch wieder freigeben. -dnh -- Es gibt in Afrika einen Stamm, die stehen auf einem Bein. Das ist deren Standart. Und weil sie immer so stehen, ist deren Standart bei denen Standard. -- Steffen Schmidt in de.comm.infosystems.www.pages.misc
participants (3)
-
David Haller
-
Michael Unterkalmsteiner
-
Stefan Hundhammer