Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Sigsegv^1000

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
08.09.2003, 15:42 Uhr
~xodi
Gast


Hi Leute!

Ich habe mal wieder ein Problem mit einigen C-Funktionen.

zum einen hab ich hier ne Funktion, die mir bei der Zeile mit dem Pfeil dauernd rausbricht:


C++:

// Puts an entry ordered into a double linked list to remember an identified directory entry
void insert(float size, char *date, char *path, int count, char *filename, int type)
{
    struct smlfilelist *p, *pbegin, *pend;
    if(debug) printf("insert %d\n", debug++);
    if((p =(struct smlfilelist *) malloc(sizeof(struct smlfilelist))) == NULL)
    {
        fprintf(stderr,"%s: Error allocating memory!\n", do_date(time((time_t *)NULL), TRUE));
        fprintf(stdout,"%s: Error allocating memory!\n", do_date(time((time_t *)NULL), TRUE));
        exit(5);    // No more memory available, that's a real problem.
    }
    p->size     = size;
    p->count    = count;
    p->date     = scopy(date);
    p->path     = scopy(path);
    p->filename = scopy(filename);                    <-------- SIGSEGV
    p->next = NULL;

    switch(type)
    {
    case 1 :
        {    pbegin = bbegin;
            pend = bend;
            break;
        }
    case 2 :
        {    pbegin = obegin;
            pend = oend;
            break;
        }
    case 3 :
        {    pbegin = lbegin;
            pend = lend;
            break;
        }
    default :
        {    pbegin = ibegin;
            pend = iend;
            break;
        }
    }

    if(pbegin == NULL)
    {
        pbegin = pend = p;
        pbegin->next = pbegin->previous = NULL;
    }
    else
    {
        p->previous = pend;
        pend->next = p;
        pend = p;
    }
    switch(type)
    {
    case 1 :
        {    bbegin = pbegin;
            bend = pend;
            break;
        }
    case 2 :
        {    obegin = pbegin;
            oend = pend;
            break;
        }
    case 3 :
        {    lbegin = pbegin;
            lend = pend;
            break;
        }
    default :
        {    ibegin = pbegin;
            iend = pend;
            break;
        }
    }

    if(debug) printf("insert Ende\n");
    return;
}




diese Funktion wird im Verlauf des Programms mehrere Male aufgerufen.
Zu bestimmten Zeitpunkten wird die Struktur zum Sichern, global deklariert durch


C++:
struct    smlfilelist *bbegin = NULL, *bend = NULL, *obegin = NULL;

,


wieder geflusht (durch free und xbegin = xend = NULL)
Sobald die Funktion das erste mal nach einem Flush der Struktur ausgeführt wird gibts blaues Auge.

Hat vielleicht jemand ne Idee?

Der Vollständigkeit halber das Makro scopy:

C++:
#define scopy(x)    strcpy(malloc(strlen(x)+1),(x))




gruß
xodi
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
08.09.2003, 15:57 Uhr
virtual
Sexiest Bit alive
(Operator)


Witzig: Da achtest du hier

C++:
if((p =(struct smlfilelist *) malloc(sizeof(struct smlfilelist))) == NULL)


ganz dolle und super gut darauf, ob auch wirklich Speicher da ist, machst aber alle Bemühungen wieder dadurch zunichte, indem du den Code mit solchen Dingen gradezu hinrichtest!

C++:
#define scopy(x)    strcpy(malloc(strlen(x)+1),(x))


Ich mein: ersetz das scopy mal durch vernünftigen Code. Dann geht der fehler vielleicht auch weg.

-edit: Fight thr rightwriteerrors (ein new hobby of mir)
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)

Dieser Post wurde am 08.09.2003 um 15:59 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
08.09.2003, 20:09 Uhr
~xodi
Gast


Hi nochmal!

Hatte das Problem dann doch gelöst. Das mit dem scopy funktioniert übrigens ganz gut. Problem war, dass ich in der Methode zum cleanen nicht alles freigegeben hab. Deswegen dann der sigsegv.
Trotzdem danke für den Tip virtual.

gruß
xodi
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
09.09.2003, 08:41 Uhr
ao

(Operator)



Zitat:
~xodi postete
Das mit dem scopy funktioniert übrigens ganz gut.

Natürlich funktioniert das gut - solange Speicher da ist. Der Ärger fängt an, wenn malloc mal schiefgeht, weil der Speicher alle ist. Du übernimmst nämlich das Ergebnis von malloc ungeprüft und steckst es in strcpy rein, und das wird irgendwann neue SIGSEGVs geben.

Ungeprüfte malloc-Aufrufe sind Zeitbomben, die irgendwann hochgehen. Hoffentlich nicht bei der Kundenpräsentation.

ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
09.09.2003, 17:52 Uhr
~xodi
Gast


hast recht, ich werde die mallocs in Zukunft alle prüfen.

Noch ne Frage zu Speicherbereichen:

wenn ich mit
C++:

dl = (struct dirnames **) malloc(sizeof(struct dirnames *) * (ne = 400));




ein Array der Strukturen definier, wie bekomm ich das nachher wieder weg?

folgendes Beispiel:


C++:
struct dirnames **read_dir(char *dir, float *thisdirsize, int *thisdirfiles, char *tname)
{
  char path[2048];
  struct dirnames **dl;
  struct dirent *ent;
  struct stat lst;
  DIR *d;
  int ne, p = 0,
      bigsize = 1024 * atoi(getvalue(tname, "bigsize")),
      olddate = time((time_t *)NULL) - atoi(getvalue(tname, "olddate"))*3600*24;

  if(debug > 0) printf("read_dir %d\n", debug++);

  if ((d=opendir(dir)) == NULL)
  {
      fprintf(stderr,"%s: [error opening directory: %s]\n",do_date(time((time_t *)NULL), TRUE), dir);
      fprintf(stdout,"%s: [error opening directory: %s]\n",do_date(time((time_t *)NULL), TRUE), dir);
      return NULL;
  }

  dl = (struct dirnames **) malloc(sizeof(struct dirnames *) * (ne = 400));

  while((ent = (struct dirent *)readdir(d)))
  {
    if ((!strcmp("..",ent->d_name)) || (!strcmp(".",ent->d_name)) || (!strncmp(".snapshot",ent->d_name, 9))) continue;

    snprintf(path,strlen(dir)+strlen(ent->d_name)+3,"%s/%s",dir,ent->d_name);


    if (lstat(path,&lst) < 0 || ((lst.st_mode & S_IFMT) == S_IFLNK))
    {
        (*thisdirfiles)++;
        continue;
    }
    if((lst.st_mode & S_IFMT) == S_IFDIR)
    {
        dl[p] = (struct dirnames*) malloc(sizeof(struct dirnames));
        dl[p++]->name = scopy(ent->d_name);
        if(p>ne) dl = (struct dirnames **) realloc(dl,sizeof(struct dirnames *) * (ne += 100));
        continue;
    }
    (*thisdirsize) += lst.st_size;
    (*thisdirfiles)++;
    
      if((float)lst.st_size > (float)bigsize)        // Is it big? -> Remember it
          insert(((float)(lst.st_size)/1024), do_date(lst.st_mtime, TRUE),dir, 0, ent->d_name, 1);
      if(olddate > lst.st_mtime)        // Is it old? -> Remember it
          insert(((float)(lst.st_size)/1024), do_date(lst.st_mtime, TRUE),dir, 0, ent->d_name, 2);
      if(!(*thisdirfiles % 10000) && communicative > 0)
          fprintf(stdout, "processing \"%s/\", I've checked %d files by now...\n", dir, *thisdirfiles);

  }
  closedir(d);
  dl[p] = NULL;
    if(debug > 0) printf("read_dir Ende\n");
  return dl;
}




Da wird also der Bereich allokiert. In der folgenden Funktion wird der Block verarbeitet:


C++:

float process_dir(char *directory, char *tname, int *filestotal, float *sizetotal, unsigned int level)
{
  struct dirnames **dir;
  char path[2048];
  float dsize = 0;
  int dfiles = *filestotal;
  dir = read_dir(directory, &dsize, filestotal, tname);
  if(debug > 0) printf("process_dir %d\n", debug++);
  if(dir)
  {
    while(*dir)
    {
        if(strlen(directory) == 1)
            snprintf(path,strlen((*dir)->name)+3,"/%s",(*dir)->name);
        else
            snprintf(path,strlen(directory)+strlen((*dir)->name)+2,"%s/%s",directory,(*dir)->name);
        dsize += process_dir(path,tname, filestotal, sizetotal, (level + 1));
        free((*dir)->name);
        free(*(dir++));
    }
  }

  insert(((float)dsize)/1024, "", directory, ((*filestotal)-dfiles), "", 3);
  if(level == 1) check_legal(tname, directory, (float)(dsize)/1024, ((*filestotal)-dfiles), strlen(getvalue(tname, "transdir")));
  if(debug > 0) printf("process_dir Ende\n");
  return dsize;
}




Wie krieg ich nun das array an sich weg? Oder wird das schon gekillt mit den verschiedenen free(*dir...)'s ?

gruß
xodi
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: