[C] programma werkt maar segfault aan einde

Pagina: 1
Acties:

  • xychix
  • Registratie: September 2000
  • Laatst online: 03-12-2025

xychix

FreeBSD Rules !

Topicstarter
Mijn programma werkt naar behoren alleen geeft een segfault aan het einde..

ook heb ik het geprobeerd met in de functie een malloc voor de char** en met een free aan het einde v/h programma..

Hierbij de source en daaronder de gdb output.

Kan iemand mij vertellen hoe ik deze segfault netjes oplos ?

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <dirent.h>
#include <string.h>

main()
{
    int i,itar;
    char **tarlist;
    itar = dirlist("/etc/",".conf",tarlist);

    printf("\nLets Go:\n");
    for(i=0;i<itar;i++)
    {
        printf("%s\n",tarlist[i]);
        free(tarlist[i]);
    }
    printf("\nDone\n");
    //free(tarlist);
}


int dirlist(const char* dirname, const char* needle, char **tarlist)
{
    struct dirent **namelist;
    int n,i,itar = 0;

    n = scandir(dirname, &namelist, 0, alphasort);
    //tarlist = (char**)malloc(sizeof(char *)*n);
    if (n < 0)
        perror("scandir");
    else
    {
        i=0;
        for(i=0;i<n;i++)
        {
            printf("%s\n", namelist[i]->d_name);
            if(strstr(namelist[i]->d_name,needle)!=NULL)
            {
                printf("  HIT %s contains %s (hit nr %d)\n",namelist[i]->d_name,needle,itar);
                tarlist[itar] = (char*)malloc(256);
                strncpy(tarlist[itar],namelist[i]->d_name,255);
                itar++;
            }
            free(namelist[i]);
        }
        free(namelist);
   }
   return(itar);
}

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ gdb  test ./core
GNU gdb 2002-04-01-cvs
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-linux"...(no debugging symbols found)...
Core was generated by `./test'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2
#0  0x40084a90 in free () from /lib/libc.so.6
(gdb)

[ Voor 11% gewijzigd door xychix op 14-10-2003 15:10 ]

Every failure offers you a new opportunity! | Lokatie database|GoT - Notepad


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 01:56
Type eens 'bt' (backtrace) in GDB, nadat je die core-file geladen hebt. ;)

  • xychix
  • Registratie: September 2000
  • Laatst online: 03-12-2025

xychix

FreeBSD Rules !

Topicstarter
Soultaker: hierbij... mij zegt het niets nieuws. Behalve dat het misgaat op een free.
code:
1
2
3
4
5
(gdb) bt
#0  0x40084a90 in free () from /lib/libc.so.6
#1  0x0804861e in main ()
#2  0x4002f14f in __libc_start_main () from /lib/libc.so.6
(gdb)


Ook gelijk het laatste stukje van
$ltrace test
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
printf("%s\n", "pam.conf"pam.conf
)                        = 9
free(0x0804b1b8)                                  = <void>
printf("%s\n", "resolv.conf"resolv.conf
)                     = 12
free(0x0804af80)                                  = <void>
printf("%s\n", "serial.conf"serial.conf
)                     = 12
free(0x0804ac08)                                  = <void>
printf("%s\n", "sysctl.conf"sysctl.conf
)                     = 12
free(0x0804ad10)                                  = <void>
printf("%s\n", "syslog.conf"syslog.conf
)                     = 12
free(0x0804b7f0)                                  = <void>
printf("%s\n", "updatedb.conf"updatedb.conf
)                   = 14
free(0x0804b088)                                  = <void>
printf("\nDone\n"
Done
)                                = 6
free(0x4012de48 <unfinished ...>
--- SIGSEGV (Segmentation fault) ---
+++ killed by SIGSEGV +++


De fout zit hem in de free van tarlist
maar met malloc in de functie dirlist() word het er niet beter op!
dan print hij helemaal geen output en klapt hij meteen na "Let's Go"

Ik denk dat de fout in de uitgecommetarieerde malloc in dirlist() zit...
nu word hij niet gemalloced dus kun je hem ook niet freeen.. maar met de malloc aan klapt ie nog eerder!

[ Voor 116% gewijzigd door xychix op 14-10-2003 14:22 ]

Every failure offers you a new opportunity! | Lokatie database|GoT - Notepad


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Je alloceert tarlist nergens :?
gebruik trouwens [code=c], dan krijg je highlighting, en dan zie je dat de regel
C:
1
//tarlist = (char**)malloc(sizeof(char *)*n);


is uitgecomment ;)
.edit: behalve in mijn highlighter, want die ondersteund dus nog geen C99 :Y)

[ Voor 18% gewijzigd door .oisyn op 14-10-2003 15:09 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • xychix
  • Registratie: September 2000
  • Laatst online: 03-12-2025

xychix

FreeBSD Rules !

Topicstarter
.oisyn schreef op 14 October 2003 @ 15:08:
Je alloceert tarlist nergens :?
gebruik trouwens [code=c], dan krijg je highlighting, en dan zie je dat de regel
C:
1
//tarlist = (char**)malloc(sizeof(char *)*n);


is uitgecomment ;)
.edit: behalve in mijn highlighter, want die ondersteund dus nog geen C99 :Y)
als ik die wel alloceer dan klapt het programma nog VOOR hij zijn output lus in main print!!

dus met
C:
1
    tarlist = (char**)malloc(n);

krijgen we: (ltrace ouput)


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
strstr("syslog.conf", ".conf")                    = ".conf"
printf("  HIT %s contains %s (hit nr %d)"..., "syslog.conf", ".conf", 22  
             HIT syslog.conf contains .conf (hit nr 22)
) = 45
malloc(256)                                       = 0x0804abe8
strncpy(0x0804abe8, "syslog.conf", 255)           = 0x0804abe8
free(0x0804b0a8)                                  = <void>
printf("%s\n", "terminfo"terminfo
)                        = 9
strstr("terminfo", ".conf")                       = NULL
free(0x0804af20)                                  = <void>
printf("%s\n", "timezone"timezone
)                        = 9
strstr("timezone", ".conf")                       = NULL
free(0x0804b108)                                  = <void>
printf("%s\n", "updatedb.conf"updatedb.conf
)                   = 14
strstr("updatedb.conf", ".conf")                  = ".conf"
printf("  HIT %s contains %s (hit nr %d)"..., "updatedb.conf", ".conf", 23  
             HIT updatedb.conf contains .conf (hit nr 23)
) = 47
malloc(256)                                       = 0x0804acf0
strncpy(0x0804acf0, "updatedb.conf", 255)         = 0x0804acf0
free(0x0804ae58)                                  = <void>
free(0x0804b568)                                  = <void>
printf("\nLets Go:\n"
Lets Go:
)                            = 10
printf("%s\n", "EOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOFEOF"... <unfinished ...>
--- SIGSEGV (Segmentation fault) ---
+++ killed by SIGSEGV +++

[ Voor 98% gewijzigd door xychix op 14-10-2003 15:14 ]

Every failure offers you a new opportunity! | Lokatie database|GoT - Notepad


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ja maar waar moeten de tarlist entries dan in komen te staan? In je oorpsronkelijke code in je topicstart is tarlist een ongeinitializeerde variabele. Die kan dus overal naar wijzen, maar iig niet naar een eigen stukje geheugen. En dan ga je vervolgens wel entries in de array toekennen. Dat kan toch niet goed gaan?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • xychix
  • Registratie: September 2000
  • Laatst online: 03-12-2025

xychix

FreeBSD Rules !

Topicstarter
.oisyn schreef op 14 October 2003 @ 15:16:
Ja maar waar moeten de tarlist entries dan in komen te staan? In je oorpsronkelijke code in je topicstart is tarlist een ongeinitializeerde variabele. Die kan dus overal naar wijzen, maar iig niet naar een eigen stukje geheugen. En dan ga je vervolgens wel entries in de array toekennen. Dat kan toch niet goed gaan?
ik heb nu de malloc code aangezet... dus tarlist heeft ruimte voor n char *......
iedere char* wijst naar een verderop gemallloc'te char array van 255 tekens.

dat is toch correct ????

[ Voor 18% gewijzigd door xychix op 14-10-2003 15:23 ]

Every failure offers you a new opportunity! | Lokatie database|GoT - Notepad


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ja sorry hoor maar dit komt zo onderhand neer op P&W FAQ - Leer **** debuggen!!

Waar crasht ie nu? Op printf (). Waarom? Omdat je parameters blijkbaar niet kloppen (dat zie je ook, de string wijst naar EOFEOFEOFEOF... Dat moet je toch al een idee geven dat daar iets niet goed zit)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • xychix
  • Registratie: September 2000
  • Laatst online: 03-12-2025

xychix

FreeBSD Rules !

Topicstarter
dus iets wat je in een functie malloced word WEL vrijgegeven bij het verlaten van de funcite ?? dat is mijn conclusie na het toevoegen van een aantal printfjes in de source...

kan ik dat ook voorkomen ???

ja ik ga ook al in een boek kijken....

[ Voor 10% gewijzigd door xychix op 14-10-2003 15:39 ]

Every failure offers you a new opportunity! | Lokatie database|GoT - Notepad


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04:06

.oisyn

Moderator Devschuur®

Demotivational Speaker

dus iets wat je in een functie malloced word WEL vrijgegeven bij het verlaten van de funcite ?? dat is mijn conclusie na het toevoegen van een aantal printfjes in de source...
je zou bijvoorbeeld eens een C boek kunnen kopen oid, dan had je geweten dat dat ook niet het geval is.

Wat wel het geval is is dat tarlist een gewone parameter is in je dirlist functie. Als je tarlist daar wijzigt dan wijzigt ie natuurlijk niet mee in je aanroepende main (). Je zult dus een pointer mee moeten geven van tarlist

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

.oisyn schreef op 14 October 2003 @ 15:43:
Je zult dus een pointer mee moeten geven van tarlist
offtopic:
woei 3 sterretjes! wie biedt er meer? ;)

Professionele website nodig?


  • xychix
  • Registratie: September 2000
  • Laatst online: 03-12-2025

xychix

FreeBSD Rules !

Topicstarter
ook met de genoemde links kom ik er niet uit.. misschien moet ik maar weer bij het begin beginnen..


hmmm zou ik jullie bijna jankend gelijk geven
alleen een testje wees uit dat DIT: wel werkt....
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
main()
{
   char * test;
   char ** list;

   test = (char*)malloc(sizeof(char)*12);
   strcpy(test,"blaa");  // test word succesvol gewijzigd door strcpy
   printf("test %s\n\n",test);
   free(test);

   list = (char**)malloc(sizeof(char*)*3);
   list[1] = (char*)malloc(sizeof(char)*12);
   list[0] = (char*)malloc(sizeof(char)*12);

   listcopy(list,"bla1","bla2");
   printf("listtest0 %s\n",list[0]);//de list is ook gewijzigd!
   printf("listtest1 %s\n",list[1]);
   free(list[0]);
   free(list[1]);
   free(list);
}

int listcopy(char** list, const char* txt1, const char* txt2)
{
   strcpy(list[0],txt1);
   strcpy(list[1],txt2);
}


nu eens testen of ik de malloc ook naar de listcopy functie kan verplaatsen

K blaat weer ozin... natuurlijk kun je die malloc niet verplaatsen want dan word het adres van list veranderd 8)7 8)7 k snap m eindelijk.
hoe het nu wel zou moeten weet ik nog niet.... maar ik zie de fout...

mijn excuses!

ik zou een char***p mee kunnen (willen) geven, en dan achteraf
list = *p;
helaas wil ik te snel.. wat dat lostt niet op :) overigens gaat mijn kernigan and ritchie boek niet zover.....

maar dit lost het ook niet op. blijf wel bezig maar kan maar geen documentatie vinden die hierop in gaat en ik kan mijn eigen gedachten kronkel ook niet vinden.
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int listcopy(char** list, const char* txt1, const char* txt2);

main()
{
   char ** list;
   char ***p;

   listcopy(p,"bla1","bla2");
   list=*p;
   
   printf("listtest0 %s\n",list[0]);//de list is ook gewijzigd!
   printf("listtest1 %s\n",list[1]);
   free(list[0]);
   free(list[1]);
   free(list);
}


het enige wat ik nog kan bedenken is gewoon een void *p aan de funcitie meegeven deze maar de malloc ruimte laten wijzen..
dan een in de functie aangemaakte
char **templist = (char**)p;
en vervolgens in de hoofdroutine ook weer
char **list = (char**)p;
maar da's niet erg netjes... en ik kan nu ff niet testen of dat uberhaupt wel werkt

[ Voor 84% gewijzigd door xychix op 14-10-2003 18:43 ]

Every failure offers you a new opportunity! | Lokatie database|GoT - Notepad


  • xychix
  • Registratie: September 2000
  • Laatst online: 03-12-2025

xychix

FreeBSD Rules !

Topicstarter
Vele uren later......
Ik heb een draaiend programma dat niet meer segfault.. alleen list[1] word niet goed gevuld...

Waarom is de inhoud van list[0] (null) ???????????

dit is de output van het programma:

code:
1
2
3
4
5
$ ./lo
hier komen we wel

listtest0 bla1
listtest1 (null)

Het programma zelf...
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
int listcopy(char*** list, const char* txt1, const char* txt2);

int main()
{
   char** list;

   listcopy(&list,"bla0","bla1");

   printf("hier komen we wel\n\n");

   printf("listtest0 %s\n",list[0]);
   printf("listtest1 %s\n",list[1]);
   free(list[0]);
   free(list[1]);
   free(list);

   return(0);
}

int listcopy(char*** list, const char* txt1, const char* txt2)
{
   *list = (char**)malloc(sizeof(char*)*4);
   *list[0] = (char*)malloc(sizeof(char)*12);
   *list[1] = (char*)malloc(sizeof(char)*12);

   strcpy(*list[0],txt2);
   strcpy(*list[1],txt1);

   return(0);
}



na veel gemekker heb ik mijn eigen onkunde onderkend en de door Buzzcode aangedragen oplossing gebruikt:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>

 char **listcopy( int* num, const char * txt0, const char * txt1)
 {
  char **list;
  list = malloc( sizeof( char * ) * 2 );
  list[0] = malloc(50 );
  strcpy( list[0], txt0 );
  list[1] = malloc(50);
  strcpy( list[1], txt1 );
  *num = 2;
  return list;
 }

 int main()
 {
  char **list;
  int num, i;
  list = listcopy( &num , "bla0" , "bla1" );

  for ( i = 0; i < num; i++ )
   printf( "%s\n", list[i] );

  for ( i = 0; i < num; i++ )
   free( list[i] );
  free (list );
  return 0;
}

[ Voor 30% gewijzigd door xychix op 15-10-2003 07:47 ]

Every failure offers you a new opportunity! | Lokatie database|GoT - Notepad


  • madwizard
  • Registratie: Juli 2002
  • Laatst online: 26-10-2024

madwizard

Missionary to the word of ska

Maak van alle *list[x] eens (*list)[x] :). *list[x] is namelijk *(list[x]) en dat is heel wat anders ;)

www.madwizard.org


  • xychix
  • Registratie: September 2000
  • Laatst online: 03-12-2025

xychix

FreeBSD Rules !

Topicstarter
Thanks... idd dat was het!

CASE CLOSED :P

werkende versie voor het archief:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>

int listcopy(char*** list, const char* txt1, const char* txt2);

int main()
{
   char** list;

   listcopy(&list,"bla0","bla1");

   printf("hier komen we wel\n\n");

   printf("listtest0 %s\n",list[0]);
   printf("listtest1 %s\n",list[1]);
   free(list[0]);
   free(list[1]);
   free(list);

   return(0);
}

int listcopy(char*** list, const char* txt1, const char* txt2)
{
   *list = (char**)malloc(sizeof(char*)*4);
   (*list)[0] = (char*)malloc(sizeof(char)*12);
   (*list)[1] = (char*)malloc(sizeof(char)*12);

   strcpy( (*list)[0],txt2);
   strcpy( (*list)[1],txt1);

   return(0);
}

[ Voor 94% gewijzigd door xychix op 15-10-2003 10:49 ]

Every failure offers you a new opportunity! | Lokatie database|GoT - Notepad

Pagina: 1