[solved]Nieprawidlowe przekazywanie referencji?

0

Cześć,

Zapragnąłem przygotować funkcję, która wspierać będzie moją współpracę z regex'em. Funkcja wygląda tak:

int regex(char * string, char * pattern, regmatch_t match[], exception_event exception_function)
{
    regex_t regex;


    int resultRegcomp = regcomp(&regex, pattern, REG_NEWLINE|REG_ICASE|REG_EXTENDED);


    if (resultRegcomp != 0)
    {
        (* exception_function)(regex_error(resultRegcomp, &regex));

        regfree(&regex);

        return -1;
    }
    else
    {
        match = (regmatch_t *)malloc(sizeof(regmatch_t) * regex.re_nsub);


        if (match == 0)
        {
            (* exception_function)("In regex function can't malloc memory");

            regfree(&regex);

            return -2;
        }
        else
        {
            int resultRegexec = regexec(&regex, string, regex.re_nsub, match, 0);


            if (resultRegexec == 0)
            {
                printf("%d %d\n", match[1].rm_so, match[1].rm_eo);

                regfree(&regex);

                return regex.re_nsub;
            }
            else
            {
                (* exception_function)(regex_error(resultRegexec, &regex));

                regfree(&regex);

                return -3;
            }
        }
    }


    return 0;
}

Dwa pierwsze i ostatni parametr działają bez problemu. Problem mam z parametrem trzecim. Przy takim wywołaniu w funkcji main:

int main(int argc, char * argv[])
{
    regmatch_t * match;


    int resultRegex = regex("2 TEXT CODE", "^([0-9]{1,})(\\s+)(.+)$", match, exception);


    if (resultRegex > 0)
    {
        printf("Result: %d, Start: %d, End: %d\n", resultRegex, match[1].rm_so, match[1].rm_eo);
    }


    return 0;
}

Spodziewałem się tego, że match[1] zwróci mi poprawną wartość. Niestety wygląda na to, że marzę po pamięci. Nie bardzo wiem co może być tego powodem, a już dawno nie pracowałem w C :/

Poproszę Was o pomoc.

0

int regex(char * string, char * pattern, regmatch_t match[], exception_event exception_function)
{
......
}

a wywołujesz:

regmatch_t *match;

nt resultRegex = regex("2 TEXT CODE", "^([0-9]{1,})(\s+)(.+)$",match, exception);

zamień Bracie w deklaracji funkcji przyjmowanie 3 argumentu w postaci tablicy na wskaźnik,i powinno grać

0

Nie bardzo rozumiem. Możesz mi szczegółowiej to opisać?

--
Edit: zmieniłem deklarację funkcji na regmatch_t * match. Niestety nic to nie zmieniło :/

0

hmmm ja tam jeszcze widzę taką podejrzaną linię:

int resultRegcomp = regcomp(&regex, pattern,REG_NEWLINE|REG_ICASE|REG_EXTENDED);

temu obiektowi regex trzeba by chyba przypisać ów *string z wywołania,no nie Bracie?Bo jak inaczej ma porównać?

aha,i weź wytłumacz(tzn zarzuć dokumentacją lub linkiem) co to takiego regmatch_t i regex_t

0
MasterBLB napisał(a)

int regex(char * string, char * pattern, regmatch_t match[],
....
zamień Bracie w deklaracji funkcji przyjmowanie 3 argumentu w postaci tablicy na wskaźnik,i powinno grać

zmiana nic nie da, poniewaz typ regmatch_t[] jest tozsamy z regmatch_t*

MasterBLB napisał(a)

hmmm ja tam jeszcze widzę taką podejrzaną linię

i kolejna rzecz, "Bracie", ta linia nie jest podejrzana, tylko wlasnie ona sluzy inicjowaniu zmiennej typu regex_t. funkcja regcomp to wywolanie kompilatora wyrazenia regularnego. zamiast prosic o wytlumaczenia, radzilbym Ci bardziej uwazac co piszesz, albo - wstepnie samemu zagladac do literatury tematu na ktory odpowiadasz, albo wrecz - stosowac zasade "nie wiem-nie mowie"

a wracajac do konkretnego problemu, blad tkwi tu:

int regex(char * string, char * pattern, <b>regmatch_t match[],</b>
...
        match = (regmatch_t *)malloc(sizeof(regmatch_t) * regex.re_nsub);

zmienna/parametr MATCH jest pobierana przez Twoja funkcje poprzez WARTOSC. to znaczy, zmienna 'match' jest lokalna kopia tego co bylo na zewnatrz i totozewnetrzne sie nie zmieni [to, ze ja sobie podstawiasz zwrotem malloc'a - ok - ale na zewnatrz tej zmiany nie bedzie widac. zmieniasz wartosc lokalnej kopii].

zeby bylo, to musisz ja jakos przekazac poprzez adres/referencje.
w C++, przez referencje:

int regex(char * string, char * pattern, <b>regmatch_t (&match)[],</b>
...
        match = (regmatch_t *)malloc(sizeof(regmatch_t) * regex.re_nsub);

w C i C++, poprzez adres:

int regex(char * string, char * pattern, <b>regmatch_t (*match)[],</b>
...
        *match = (regmatch_t *)malloc(sizeof(regmatch_t) * regex.re_nsub);

uwaga: przekazanie przez-adres jest defacto prezkazaniem przez wartosc. roznica polega na tym, ze tutaj przez wartosc przekazujesz adres-tamtej-zmiennej-z-zewnatrz, a nie wartosc tej zmiennej. dzieki temu *match=xxxx spowoduje bezposrednie zmodyfikowanie zmiennej 'z zewnetrza' funkcji, a nie tylko jakiejs lokalnej kopii..

0

Quetzalcoatl dzięki, pomogło :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1