Array und Int in main() übergeben, C

mogbo

Banned
Hallo,
ich bekomm es leider nicht hin meinen 2D char ovpn_arry und int i in meine main() Funktion zu übergeben. Könnte mir hier jemand helfen, am besten so, dass ich es verstehe :). Sind sicher viele Anfängerumständlichkeiten im Code, nehme da auch gerne Tipps entgegen.

Ausschnitt aus meiner ovpn.c
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/types.h>
#include <dirent.h>

char *
ls_ovpn(char path[], int ovpn_minlen, int i, int ovpn_row, int ovpn_char)
{
    char ovpn_array[ovpn_row][ovpn_char];

    DIR *ovpn_path;
    struct dirent *ovpn_dir;

    ovpn_path = opendir(path);

    if(ovpn_path == NULL) {
        printf("%s nicht moeglich\n", path);
        exit(1);
    }

    while((ovpn_dir = readdir(ovpn_path)) != NULL) {
        const size_t len = strlen(ovpn_dir->d_name);

        /* Nach Dateiendung suchen */
        if( len > ovpn_minlen                   &&
            ovpn_dir->d_name[len - 4] == 'o'    &&
            ovpn_dir->d_name[len - 3] == 'v'    &&
            ovpn_dir->d_name[len - 2] == 'p'    &&
            ovpn_dir->d_name[len - 1] == 'n'        ) {

            /* Ausgabe des Ordnerinhalts in 2D-Array packen und \0 */
            strlcpy(&ovpn_array[i][0], ovpn_dir->d_name, ovpn_char - 1);
            ovpn_array[i][ovpn_char -1] = '\0';

            printf("[%i]\t%s\n", i, ovpn_array[i]);
            i++;
        } else {
            continue;
        }
    }
    closedir(ovpn_path);

    return 0; /* was muss hier stehen, statt 0? */
}

int
main()
{
    ls_ovpn("/etc/openvpn", 4, 0, 20, 20);
    return 0;
}
Komm seit Stunden nicht weiter und bekomme leider die ergoogelten Guides nicht auf meine Funktion übersetzt.
 
In C können Funktionen nur einen Wert zurückgeben. Außerdem legt die Funktion ls_ovpn() das Array ovpn_array[][] auf dem Stack an. Es ist also nur solange gültig, wie auch ls_ovpn() auf dem Stack liegt. Ist ls_ovpn() durchlaufen worden und das Programm kehrt in main() zurück, fallen sowohl die Funtion ls_ovpn() als auch all ihre Inhalte inklusive dem Array ovpn_array[][] vom Stack und sind damit erstmal gelöscht. Wenn du ovpn_array[][] oder einen Zeiger / Pointer darauf an main() zurückgibst, zeigst du daher auf nicht mehr vorhandenen Speicher. Das ist undefiniertes Verhalten, bestenfalls stürzt das Programm mit einem Segfault ab. Der einfachste und auf den ersten Blick auch beste Ausweg wäre, sowohl ovpn_array[][] als auch i in main() anzulegen und als Pointer an ls_ovpn() zu übergeben. Dann kann ls_ovpn() darauf arbeiten und main() hat die Daten später direkt und ohne weitere Maßnahmen zur Verfügung.
 
Wenn du ovpn_array[][] oder einen Zeiger / Pointer darauf an main() zurückgibst, zeigst du daher auf nicht mehr vorhandenen Speicher.
Achso, habe Pointer übergeben und mich über die Ausgabe (null) schon gewundert :)

Mit einem malloc habe ichs auch hinbekommen, wurde aber in mehreren Foren als "unschön" bezeichnet, somit wollte ich keinen solchen Workaround verwenden.

Der einfachste und auf den ersten Blick auch beste Ausweg wäre, sowohl ovpn_array[][] als auch i in main() anzulegen und als Pointer an ls_ovpn() zu übergeben. Dann kann ls_ovpn() darauf arbeiten und main() hat die Daten später direkt und ohne weitere Maßnahmen zur Verfügung.
Hört sich auch nach einer schönen Übung an, genau so werd ichs machen

Vielen Dank!
 
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/types.h>
#include <dirent.h>

/*
 *  Funktion durchsucht den Pfad nach Dateiendungen     
 */
void
ls_ovpn(char path[], int *i, int ovpn_minlen, int ovpn_row, int ovpn_char, char ovpn_array[ovpn_row][ovpn_char])
{
    DIR *ovpn_path;
    struct dirent *ovpn_dir;

    ovpn_path = opendir(path);

    if(ovpn_path == NULL) {
        printf("%s nicht moeglich\n", path);
        exit(1);
    }

    while((ovpn_dir = readdir(ovpn_path)) != NULL) {
        const size_t len = strlen(ovpn_dir->d_name);

        /* Nach Dateiendung suchen */
        if( len > ovpn_minlen                   &&
            ovpn_dir->d_name[len - 4] == 'o'    &&
            ovpn_dir->d_name[len - 3] == 'v'    &&
            ovpn_dir->d_name[len - 2] == 'p'    &&
            ovpn_dir->d_name[len - 1] == 'n'        ) {

            /* Ausgabe des Ordnerinhalts in 2D-Array packen und \0 */
            strlcpy(&ovpn_array[*i][0], ovpn_dir->d_name, ovpn_char - 1);
            ovpn_array[*i][ovpn_char -1] = '\0';

            printf("[%i]\t%s\n", *i, ovpn_array[*i]);
            ++*i;
        } else {
            continue;
        }
    }
    closedir(ovpn_path);
}

int
main()
{
    int main_i = 0;
    int main_ovpn_row = 20;
    int main_ovpn_char = 20;
    int main_ovpn_minlen = 4;
   
    char main_ovpn_array[main_ovpn_row][main_ovpn_char];
   
    ls_ovpn("/etc/openvpn", &main_i, main_ovpn_minlen, main_ovpn_row, main_ovpn_char, main_ovpn_array);
   
    return 0;
}

Um den Thread zu vervollständigen :)
 
Zurück
Oben