Calocybe: (C/C++) Übergabe der Umgebungsvariablen in C Funktioniert nicht

Beitrag lesen

Hallo Sven!

»»     string = getenv("QUERY_STRING");
Mit dieser Übergabe habe ich Speicherprobleme. Dort bekomme ich immer die Meldung mit dem Speicherfehler. Der Debugger hält dort.

Das finde ich sehr seltsam, denn hier wird einfach ein Pointer nach 'string' geschrieben, da sollte eigentlich nichts schief gehen koennen. Nur falls der Pointer ungueltig ist (NULL) und spaeter darauf zugegriffen wird, waere die Schutzverletzung nachvollziehbar.

Hier wird der Wert der Umgebungsvariablen an die Variable string übergeben. Zumindest sollte das Programm das tun.

Bei C/C++ sollte man das etwas genauer nehmen: Es wird der von getenv() gelieferte Pointer in die Variable 'string' geschrieben. Solange nichts damit getan wird und der Pointer einfach in der Variable herumlungert, sollte nichts schlimmes passieren koennen.

Am besten man fürhrt das komplette Programm mal aus, dann sieht man den Fehler.

*g* Ich kenne diese Meldung sehr gut. ;-) Sie tritt eigentlich bei jedem C-Programm irgendwann mal auf, solange man in der Entwicklungsphase ist.

Na, wie auch immer, habe jetzt mal ein bisschen gecoded und folgende kleine Programme laufen auf meiner Windose ganz gut. Hab sie nur von der Kommandozeile aus gestartet, aber wenn der Webserver ordentlich konfiguriert ist, sollte es als CGI auch einfach laufen.

listenv.c listet Dir zu Testzwecken alle Environmentvariablen auf.
dumpqs.cpp analysiert den Query string und gibt die einzelnen Teile aus.
Dort wo in dumpqs.cpp die Ausgabe von *name und *value gemacht wird, muesstest Du nun einfach mit strdup() bzw. strcpy() die Strings in Deine Variablen zur Weiterverarbeitung kopieren. Dazu muesstest Du vielleicht einen Stringvergleich durchfuehren, so in der Art:
    if (strcmp(name, "email") == 0) strcpy(email, name);
    else if (strcmp(name, "homepage") == 0) strcpy(homepage, name);
Meine Variable 'name' bedeutet aber was anderes als Deine; benenne sie einfach um.

Falls Du Fragen hast, musst Du sie stellen. ;-)

Bye, Calocybe

listenv.c >>>

#include <stdio.h>

int main(int argc, char ** argv, char ** envv) {
    char ** envp;

printf("Content-Type: text/plain\n\n");

envp = envv;
    while (*envp) {
        printf("%s\n", *envp);
        envp++;
    }

return 0;
}

<<<<<<<<<<<<<<<<<

dumpqs.cpp >>>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char * qs;

int cgiargc;
char ** cgiargv;

char * strdup(char * src) {
    return src ? strcpy((char *) malloc((strlen(src) + 1) * sizeof(char)), src) : NULL;
}

int split_by_char(char *** psectionv, char * s, char splitchar, int maxsections = 0) {
    char *c, *c2, *section;
    char ** sectionv;
    int pieces, i, j;

/* first count the elements in s */
    c = s; pieces = 0;
    while (*c)
        if (*c++ == splitchar) pieces++;

if (c != s) pieces++;       /* pieces is 1 more than # of splitchars, except strlen(s)==0 */
    if (maxsections && (pieces > maxsections)) pieces = maxsections;

/* abort if s is empty */
    if (!pieces) {
        *psectionv = NULL;
        return 0;
    }

/* alloc mem for the several sections */
    *psectionv = sectionv = (char **) malloc(pieces * sizeof(char *));
    if (!sectionv) return 0;                        /* out of memory? */
    for (i=0; i<pieces; i++) sectionv[i] = NULL;    /* init all strings to NULL for safety */

/* extract the several sections */
    c = s;
    for (i=0; i<pieces; i++) {
        if (i == pieces-1)                          /* if this is the last section */
            c2 = strchr(c, '\0');                   /* copy all upto the terminating zero */
        else c2 = strchr(c, splitchar);

sectionv[i] = section = (char *) malloc((size_t) c2 - (size_t) c + (size_t) 1);
        if (!section) return pieces;                /* out of memory? */

/* copy the piece to *section */
        j = 0;
        while (c < c2) section[j++] = *c++;
        section[j] = '\0';

/* go on with the next section */
        c++;
    }

return pieces;
}

int main(int argc, char ** argv, char ** envv) {
    int i;
    char *name, *value;

printf("Content-Type: text/plain\n\n");

/* get and output the query string */
    qs = getenv("QUERY_STRING");
    if (!qs) {
        printf("QUERY_STRING not here!\n");
        return 0;
    }

printf("QUERY_STRING is >>%s<<\n", qs);

/* get and output the several sections within the query string */
    cgiargc = split_by_char(&cgiargv, qs, '&');
    printf("# of pieces in QS: %d\n", cgiargc);
    for (i=0; i<cgiargc; i++)
        printf("piece[%d] is >>%s<<\n", i, cgiargv[i]);

/* get and output the two pieces of each section */
    for (i=0; i<cgiargc; i++) {
        name = strdup(cgiargv[i]);
        if (!name) continue;

value = strchr(name, '=');
        if (value) {
            *value++ = '\0';
            printf("parameter '%s' has the value '%s'\n", name, value);
        } else printf("parameter '%s' has no value\n");

free((void *) name);
    }

/* release the memory of cgiargv */
    for (i=0; i<cgiargc; i++) free((void *) cgiargv[i]);
    free((void *) cgiargv);

return 0;
}

<<<<<<<<<<<<<<<<<<