Frage

Ich brauche Hilfe bei dieser, da es mir in meinem C-Programm Leitbleche

Ich habe 2 Strings (Basis, und Pfad)

BASE: /home/steve/cps730
PATH: /page2.html

Dies ist, wie printf liest dann, kurz bevor ich einen sprintf nennen ihre Inhalte miteinander zu verbinden. hier ist der Codeblock

        int memory_alloc = strlen(filepath)+1;
        memory_alloc += strlen(BASE_DIR)+1;
        printf("\n\nAlloc: %d",memory_alloc);
        char *input = (char*)malloc(memory_alloc+9000);
        printf("\n\nBASE: %s\nPATH: %s\n\n",BASE_DIR,filepath);
        sprintf(input, "%s%s",BASE_DIR,filepath); //   :(

        printf("\n\nPATH: %s\n\n",input);

Sie können nun erklären, wie die letzte printf Anweisung gibt

PATH: e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/stev

, weil sie nicht verstehen überhaupt.

** Ich habe 9000 in der malloc Erklärung Programm, um zu verhindern (da die Größe der Zeichenfolge Absturz ist offensichtlich größer als 31 Bytes.

Voll Ausgabe

Alloc: 31

BASE: /home/steve/cps730
PATH: /page2.html



PATH: /home/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/steve/cps730e/stev

Sending: 
HTTP/1.0 404 Not Found
Date: Sat, 12 Sep 2009 19:01:53 GMT
Connection: close

EDIT ................... der gesamte Code, der diese Variablen verwendet

const char *BASE_DIR = "/home/steve/cps730";
 char* handleHeader(char *header){
    //Method given by browser (will only take GET, POST, and HEAD)
    char *method;
    method = (char*)malloc(strlen(header)+1);
    strcpy(method,header);
    method = strtok(method," ");

    if(!strcmp(method,"GET")){
        char *path = strtok(NULL," ");
        if(!strcmp(path,"/")){
            path = (char*)malloc(strlen(BASE_DIR)+1+12);
            strcpy(path,"/index.html");
        }
        free(method);
        return readPage(path);
    }
    else if(!strcmp(method,"POST")){

    }
    else if(!strcmp(method,"HEAD")){

    }
    else{
        strcat(contents,"HTTP/1.1 501 Not Implemented\n");
                strcat(contents, "Date: Sat, 12 Sep 2009 19:01:53 GMT\n");
                strcat(contents, "Connection: close\n\n");
    }
    free(method);

}

//Return the contents of an HTML file
char* readPage(char* filepath){
    int memory_alloc = strlen(filepath)+1;
    memory_alloc += strlen(BASE_DIR)+1;
    printf("\n\nAlloc: %d",memory_alloc);
    char *input = (char*)malloc(memory_alloc+9000); 
    printf("\n\nBASE: %s\nPATH: %s\n\n",BASE_DIR,filepath);
    sprintf(input, "%s%s\0",BASE_DIR,filepath);

    printf("\n\nPATH: %s\n\n",input);

    FILE *file;
    file = fopen(input, "r");
    char temp[255];
    strcat(contents,"");

    if(file){
        strcat(contents, "HTTP/1.1 200 OK\n");
                strcat(contents, "Date: Sat, 12 Sep 2009 19:01:53 GMT\n");
                strcat(contents, "Content-Type: text/html; charset=utf-8\n");
                strcat(contents, "Connection: close\n\n");

        //Read the requested file line by line
        while(fgets(temp, 255, file)!=NULL) { 
            strcat(contents, temp);         
        }
    }
    else{
        strcat(contents, "HTTP/1.0 404 Not Found\n");
                strcat(contents, "Date: Sat, 12 Sep 2009 19:01:53 GMT\n");
                strcat(contents, "Connection: close\n\n");
    }

    return contents;
}
War es hilfreich?

Lösung

Sie rufen readPage mit einer ungültigen Zeiger path - er zeigt in die Speicher zuvor mit dem method Zeiger zugeordnet, der direkt befreit wird, bevor der Anruf an readPage. Der nächste malloc kann diesen Speicher wieder verwenden und dann kann alles passieren ...

Andere Tipps

Nun, klar kann dies nicht passieren: -)

Meine Vermutung ist, dass Ihr Haufen schrecklich bereits beschädigt ist.

würde ich auf dem tatsächlichen Zeigerwert von filepath, Eingabe- und Base suchen. Ich frage mich, wenn Sie, dass die Eingabe ganz in der Nähe zu finden, ist zu dateipfad?

würde ich auch an, wie filepath, Base etc ursprünglich erstellt wurden, können Sie einen Puffer Überlauf haben da?

Versuchen Sie diesen Code ein:

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
    const char* BASE_DIR = "/home/steve/cps730";
    const char* filepath = "/page2.html";
    int memory_alloc = strlen(filepath);
    memory_alloc += strlen(BASE_DIR)+1;
    printf("\n\nAlloc: %d",memory_alloc);
    char *input = (char*)malloc(memory_alloc);
    printf("\n\nBASE: %s\nPATH: %s\n\n",BASE_DIR,filepath);
    sprintf(input, "%s%s",BASE_DIR,filepath); //   :(

    printf("\n\nPATH: %s\n\n",input);

    return 0;
}

Wenn dies kein Problem hat, dann muss es etwas falsch an anderer Stelle im Code. Das ist, wie nicht definiertes Verhalten manchmal manifestieren sich (vermasselt, wie in keinem Zusammenhang Code funktioniert).

(BTW, ich habe +1 nicht auf beiden Strlen Anrufe, da die verkettete Zeichenfolge noch wird nur ein Null-Terminator haben.)

Da der BASE_DIR Wert wiederholt sich, entweder BASE_DIR oder filepath wahrscheinlich überlappt die in input Speicher.

Stellen Sie sicher, beide BASE_DIR und filepath wirklich zugewiesenen Speicher hat.

Ein erster Versuch ist nur eine lokale Kopie BASE_DIR und filepath macht vor sprintf aufrufen.

Aaah - der Nervenkitzel der Jagd wie die Frage, Morphs, während wir versuchen, das Problem zu lösen

Der aktuelle Code wie folgt aussieht:

const char *BASE_DIR = "/home/steve/cps730";

//Handles the header sent by the browser
char* handleHeader(char *header){
    //Method given by browser (will only take GET, POST, and HEAD)
    char *method;
    method = (char*)malloc(strlen(header)+1);
    strcpy(method,header);
    method = strtok(method," ");

    if(!strcmp(method,"GET")){
        char *path = strtok(NULL," ");
        if(!strcmp(path,"/")){
                path = (char*)malloc(strlen(BASE_DIR)+1+12);
                strcpy(path,"/index.html");
        }
        free(method);
        return readPage(path);
    }
    ...

Frage: wenn dies in einem Web-Server ausgeführt wird, ist es sicher, die gewinde unsichere Funktion strtok() zu verwenden? Ich werde ‚Ja, es ist sicher‘ zu übernehmen, obwohl ich nicht ganz überzeugt bin. Haben Sie die header Zeichenfolge gedruckt? Haben Sie den Wert path gedruckt? Haben Sie wirklich die Absicht, die zugewiesene path undicht? Wissen Sie, dass die malloc() + strcpy() Sequenz nicht BASE_DIR in path kopiert?


Die ursprüngliche Version des Codes endete mit:

 printf("\n\nPATH: %s\n\n", filepath);

Damit die ursprüngliche vorgeschlagene Teilantwort:

  

Sie formatieren in input; Sie drucken aus filepath?


Was ist die Chance, dass filepath Punkte bereits Speicher freigegeben? Wenn Sie den Speicher zuweisen, könnten Sie etwas passiert mit dem quasi-zufälligen Bereich bekommen, die filepath verwendet zu zeigen. Eine andere Möglichkeit könnte sein, dass filepath ist ein Zeiger auf eine lokale Variable in einer Funktion, die zurückgegeben hat -. So verweist er auf irgendwo zufällig in dem Stapel, die von anderen Code, wie sprintf() wieder verwendet wird

ich auch in einem Kommentar erwähnt, die Sie möglicherweise benötigen könnten, dass malloc(), um sicherzustellen, erklärt ist, und überprüfen Sie den Rückgabewert von ihm. Die Besetzung ‚(char *)‘ ist nicht zwingend in C (es ist in C ++), und viele es vorziehen, nicht die Besetzung schließen, wenn der Code streng C und nicht zweisprachig in C und C ++.


Dieser Code funktioniert für mich:

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

int main(void)
{
    const char *BASE_DIR = "/home/steve/cps730";
    const char *filepath = "/page2.html";

    int memory_alloc = strlen(filepath) + 1;
    memory_alloc += strlen(BASE_DIR) + 1;
    printf("\n\nAlloc: %d", memory_alloc);
    char *input = (char*)malloc(memory_alloc + 9000);
    printf("\n\nBASE: %s\nPATH: %s\n\n", BASE_DIR, filepath);
    sprintf(input, "%s%s", BASE_DIR, filepath);

    printf("\n\nPATH: %s\n\n", filepath);
    printf("\n\nPATH: %s\n\n", input);

    return(0);
}

Es produziert Fremd leere Linien plus:

Alloc: 31
BASE: /home/steve/cps730
PATH: /page2.html
PATH: /page2.html
PATH: /home/steve/cps730/page2.html

Der einfachste Weg, um herauszufinden, was los ist in einem Debugger durch die Ausführung zu verfolgen (möglicherweise Verfolgung des Assembler-Code fallen).

Ein paar Vermutungen darüber, was man vor sich gehen:

  • Speicherbeschädigung durch einen anderen Thread (scheint unwahrscheinlich, wenn dies ohne weiteres wiederholbar ist)
  • korrupte Haufen (auch unwahrscheinlich scheint, wie Sie die 2-Komponenten-Strings nach dem Aufruf malloc() Dump)
  • wie von Jonathan Leffler in einem Kommentar erwähnt, könnten Sie einen Header (vielleicht stdio.h) fehlt und der Compiler generiert die falsche calling / Stapelreihenfolge für die printf / sprintf Anrufe aufzuräumen. Ich würde erwarten, dass Sie einige der Kompilierung Warnungen sehen würde, wenn dies der Fall wäre -. Diejenigen, die Sie zur Kenntnis nehmen sollten

Welche Compiler / Ziel verwenden Sie?

dies richtig zu tun, würde ich den Code ändern:

/* CHANGED: allocate additional space for "index.html" */
method = (char*)malloc(strlen(header)+1+10);
strcpy(method,header);
method = strtok(method," ");

if(!strcmp(method,"GET")){
    char *path = strtok(NULL," ");
    if(!strcmp(path,"/")){
             /* CHANGED: don't allocate new memory, use previously allocated */
             strcpy(path,"/index.html");
    }
    /* CHANGED: call function first and free memory _after_ the call */
    char *result = readPage(path);
    free(method);
    return result;
}

Vorschläge


Es gibt nichts, offensichtlich falsch mit dem Programm. ( Update:.. na ja, es ist etwas offensichtlich jetzt zum ersten Stunde nur ein paar Zeilen wurden geschrieben, und sie hatten keine ernsthafte Fehler ) Sie müssen mehr davon schreiben. Hier sind einige Ideen:

  1. malloc(3) kehrt void * so ist es nicht notwendig sein sollte, es zu werfen. Wenn Sie eine Warnung erhalten, ist es sehr wahrscheinlich bedeutet, dass Sie nicht <stdlib.h> enthalten waren. Wenn Sie nicht sind, sollten Sie. (Zum Beispiel auf einem 64-Bit-System nicht malloc(3) Prototyping kann sehr ernst sein Einige der 64-Bit-Umgebungen nicht wirklich unterstützen K & R C: -).
  2. Warnungen Sprechen Sie bitte sicher, dass Sie sie alle auf drehen. Mit gcc können Sie die meisten von ihnen schalten Sie mit -Wall.
  3. Du bist gerade nicht den Rückgabewert von malloc(3) für einen Fehler.
  4. einen Speicher-Debugger verwenden wie Electric Fence . Es gibt viele Möglichkeiten, sieht meine Verbindung.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top