[C] probleem met struct

Pagina: 1
Acties:

  • eppie
  • Registratie: Maart 2000
  • Niet online
(overleden)
Hallo,

Mijn probleem gaat over de onderstaande code. Zoals die er nu staat
en ik run hem en geef hem een major nummer mee van bijvoorbeeld 10 krijg ik een lijst te zien
met de /dev files met major 10, geen probleem.
Zodra ik de regels met commentaar ervoor die de struct tmp vullen (maakt niet uit of ik er 1 of meerdere gebruik) krijg ik altijd nog maar 1 file te zien. :( En snap ook niet waarom, die struct is gewoon een simpel eigen structje waar ik wat variablen in zet meer niet.

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
int check_devfile(const char *name, const struct stat *status, int type)
{
        if (type == FTW_NS)
        {
                return 0;
        }

        if (type == FTW_F || type == FTW_SL)
        {
                if (status->st_mode&S_IFCHR && MAJOR(status->st_rdev) == major)
                {
                        printf("Found: %s\n",name);
                        struct devs *tmp;
                        //tmp->path = (char *)name;
                        //tmp->major = 180;
                        //tmp->minor = MINOR(status->st_rdev);

                        devicesFound[counter] = tmp;
                        tmp = NULL;
                        counter++;
                }
        }
        return 0;
}

Struct:
C:
1
2
3
4
5
typedef struct devs {
        char    *path;
        int     major;
        int     minor;
} devs;


Output met commentaar:
code:
1
2
3
4
5
6
7
8
9
10
driver:~/project/Sourcecode/Fisco/devdetect# ./main 10
Start detecting for major:10
Found: /dev/inportbm
Found: /dev/logibm
Found: /dev/psaux
Found: /dev/atibm
Found: /dev/jbm
Found: /dev/rtc
Found: /dev/agpgart
Found: /dev/apm_bios

Output zonder commentaar:
code:
1
2
3
driver:~/project/Sourcecode/Fisco/devdetect# ./main 10
Start detecting for major:10
Found: /dev/inportbm

Alvast bedankt!

Ik hoop dat jullie zien wat ik fout doen want ik kom er niet uit :(

[ Voor 17% gewijzigd door eppie op 17-01-2006 23:51 ]


  • alx
  • Registratie: Maart 2002
  • Niet online

alx

Volgens mij declareer je in regel 13 een ptr van het type struct devs, maar je init 'm niet. Die ptr heeft dus een ongeinite/onbekende waarde. Daarna (als je comment slashes weghaalt) ga je waarden wegschrijven naar een onbekende geheugenpositie. Init die ptr eens voordat je 'm gebruikt.

  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 13-04 14:28
Ik begrijp je verhaal niet helemaal, maar neem aan dat 't erom gaat dat je de regels 14-16 weer aan zet en dan andere output krijgt? Puntje wat ik er in ieder geval in zie:

Je hoeft de name niet te casten omdat tmp->path van hetzelfde type is. Maar voor het kopieren van een char-array moet je strcpy gebruiken.
simulacrum schreef op woensdag 18 januari 2006 @ 00:18:
Volgens mij declareer je in regel 13 een ptr van het type struct devs, maar je init 'm niet. Die ptr heeft dus een ongeinite/onbekende waarde. Daarna (als je comment slashes weghaalt) ga je waarden wegschrijven naar een onbekende geheugenpositie. Init die ptr eens voordat je 'm gebruikt.
En zoals simulacrum zegt moet je de pointer initialiseren of gewoon geen gebruik maken van een pointer maar direct van een instantie. Enige wat dan veranderd is dat de variabelen uit de struct benaderbaar zijn met de "." ipv met de "->".

[ Voor 52% gewijzigd door riezebosch op 18-01-2006 00:21 ]

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16:11
C:
1
2
3
4
5
6
7
                        struct devs *tmp;
                        //tmp->path = (char *)name;
                        //tmp->major = 180;
                        //tmp->minor = MINOR(status->st_rdev);

                        devicesFound[counter] = tmp;
                        tmp = NULL;


1 Je reserveert geen ruimte voor je struct, maar maakt alleen een pointer aan. (Die je niet initialiseert) Weet je zeker dat je geen segfault hebt gehad? :) Als je toevallig die pointer ergens van een globaal ding af komt zou je nog eens moeten nadenken over je ontwerp, of in ieder geval je naamgeving.

2 Als je een string wilt kopieren kun je niet simpelweg de pointers ernaartoe kopieren. ( Tenminste, in veel gevallen niet. De kans wordt nog kleiner als die pointer een functieparameter is ) Kijk eens naar strncpy( char*, const char*, size_t )

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • alx
  • Registratie: Maart 2002
  • Niet online

alx

Direct van een instantie gebruik maken gaat ook niet lukken. Je zou dan idd "." ipv "->" moeten typen, maar aan de code te zien is het opslaan nodig voor later en een instantie is weg na het einde van het blok.

Als je name wilt kopieren moet je idd strcpy (of strncpy) gebruiken, maar het kan heel goed dat dat niet de bedoeling/nodig is aangezien name al bestaat voor het aanroepen van check_devfile en niet erin gegenereerd wordt. (Is check_devfile wel een goede naam als je ook gevonden devfile info gaat opslaan?)

Aan je output te zien denk ik dat je de gevonden structs wilt opslaan om daarna te kunnen printen. In dat geval moet je ergens ruimte declareren voor die structs. Als je niet weet hoeveel structs het worden, wordt het een malloc/realloc/free verhaaltje. Anders is een vast van te voren array reserveren minder werk om in te rammen :)

edit: Trouwens, waarom return je alleen 0? Moet je niet 1 returneren als gevonden?

[ Voor 7% gewijzigd door alx op 18-01-2006 00:54 ]


  • eppie
  • Registratie: Maart 2000
  • Niet online
(overleden)
Bedankt voor de reply's ze hebben goed geholpen en heb een paar probleempjes opgelost met malloc.

Nou heb ik echter nog 1 probleem.

Main.c
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
#include <stdio.h>
#include <unistd.h>
#include <ftw.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/sysmacros.h>
#include "devicedetect.h"

int major = 0;
int devices[25];
int *devrtn;
main (int argc, char **argv)
{
        int i = 0;

        if (argc == 2)
        {
                devices[25] = 0;
                major = atoi((const)argv[1]);
                printf("Start detecting for major:%d\n",major);
                devrtn = detectDevices(major);
                *devices = devrtn;
                for (i = 0; i<10; i++)
                {
                        devs *tmp;
                        tmp = (devs*)malloc(sizeof(devs));
                        tmp = (devs*)&devices[i];
                        printf("major:%d\tminor:%d\n",tmp->major,tmp->minor);
                }

        }
        else
        {
                exit(0);
        }
}

detectdevice.c
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 <unistd.h>
#include <ftw.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/sysmacros.h>
#include "devicedetect.h"
int devicesFound[25];
int counter = 0;
int *detectDevices(int m)
{
        major = m;
        ftw("/dev",check_devfile,3);
        return *devicesFound;
}

int check_devfile(const char *name, const struct stat *status, int type)
{

        if (type == FTW_F || type == FTW_SL)
        {
                if (status->st_mode&S_IFCHR && MAJOR(status->st_rdev) == major)
                {
                        devs *tmp;
                        tmp = (devs*)malloc(sizeof(devs));
                        strcpy(&tmp->path, &name);
                        tmp->major = major;
                        tmp->minor = MINOR(status->st_rdev);
                        devicesFound[counter] = (int)&tmp;
                        counter++;
                }
        }
        return 0;
}


Het is dus de bedoeling dat de Main via de functie detectDevice(int major) een pointer terug krijgt naar een array met pointers naar de gevonden structs welke gevuld worden in check_devfile.
Echter bestaan die structs toch niet meer als ik uit die methode ben toch?

Want ik krijg alleen de inhoud van de struct te zien in de check_devfile functie, overal er buiten zit er niets meer in.

Mijn kennis van C is niet zo groot dat ik een oplossing weet hiervoor :(

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-04 11:08

.oisyn

Moderator Devschuur®

Demotivational Speaker

Heb je wel enig idee waar je überhaupt mee bezig bent?
Main.c, regel 18, gaat mis omdat je daar devices[25] op 0 zet, terwijl de array maar 25 elementen groot is (van 0 t/m 24 is 25 elementen, positie 25 is dus het 26e element)
regel 28 malloc je een devs type die je toekent aan de pointer 'tmp', om die waarde vervolgens weer te overschrijven met een andere waarde. Gevolg: memory leak, aangezien je de pointer naar het gemallocte stuk geheugen kwijt bent en dus niet meer vrij kunt geven. Bovendien is de waarde waarmee je 'tmp' overschrijft ook compleet bogus, waarom cast je een int naar een devs? Die twee types zijn helemaal niet even groot.
Wat je met regel 22 bedoelt snap ik ook niet helemaal, maar je slaat nu het aantal devices iig op in het eerste element van de devices array.

En in detectdevice.c, regel 26, kopiëer je een string naar waar de ongeinitialiseerde tmp->path pointer dan ook naar wijst, en daarnaast vraag je het adres op van name, wat een pointer is (dus je krijgt een pointer naar een pointer)

[ Voor 8% gewijzigd door .oisyn op 18-01-2006 13:59 ]

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.


  • alx
  • Registratie: Maart 2002
  • Niet online

alx

En dat is nog niet alles...

Zelf heb ik op een gegeven moment maar eens een boekje over C doorgenomen. Dat heeft toen veel verduidelijkt voor mij. Als je niet zoveel tijd of geduld hebt, begin dan met het ptr en array deel en het dynamisch mem alloc deel. Als je dat door hebt, denk ik dat je zoiets als wat je nu probeert wel voor elkaar krijgt. Zo niet dan kunnen we er hier wel uit komen.

Ik zie dat je kort geleden met een usb driver onder linux bezig was. Het lijkt me dat je dan ook ptrs, arrays en mem mgmt helder moet hebben (maar ik weet natuurlijk niet hoe dat afgelopen is).
Nu vermoed ik nl dat we er hier niet uit gaan komen (zonder een kant en klare opl te posten), maar misschien kun je met de opmerkingen van .oisyn nog wel verder.
Pagina: 1