Pergunta

Eu preciso de alguma ajuda com isso, uma vez que me deixa perplexo no meu programa C

I tem 2 cadeias (base, e de caminho)

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

este é como printf lê, em seguida, pouco antes de eu chamar um sprintf para participar do seu conjunto de conteúdo. aqui é o bloco de código

        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);

Agora, você pode explicar como as finais instrução printf retorna

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

porque não entendo nada disso.

** eu adicionei 9000 na instrução malloc para prevenir programa de deixar de funcionar (uma vez que o tamanho da cadeia é obviamente maior, em seguida, 31 bytes.

Saída completa

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 ................... Todo o código que usa essas variáveis ??

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;
}
Foi útil?

Solução

Você chama readPage com um path ponteiro inválido - ele aponta para a memória alocada anteriormente com o ponteiro method, que é liberado imediatamente antes da chamada para readPage. O próximo malloc pode reutilizar essa memória e, em seguida, tudo pode acontecer ...

Outras dicas

Bem, claramente isso não pode acontecer: -)

Meu palpite é que a sua pilha é terrivelmente já corrompido.

Eu olhava para os valores de ponteiro reais usados ??por filepath, entrada e base. Gostaria de saber se você vai descobrir que a entrada está muito perto de filepath?

Também gostaria de olhar como filepath, base etc foram originalmente criados, você poderia ter um tampão sobre-correr lá?

Tente este código:

#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;
}

Se isto não tem um problema, então deve haver algo de errado em outras partes do código. Que seu comportamento como indefinido, por vezes, pode manifestar-se (bagunçar como independentes código funciona).

(BTW, eu não adicionar +1 para ambas as chamadas STRLEN, desde a cadeia concatenada ainda vai ter apenas um terminador NULL.)

Uma vez que o valor BASE_DIR está se repetindo, seja BASE_DIR ou filepath é, provavelmente, sobrepondo o na memória input.

Certifique-se de ambos BASE_DIR e filepath memória realmente alocou.

A primeira tentativa é fazer apenas uma cópia local do BASE_DIR e filepath antes de chamar sprintf.

Aaah - a emoção da perseguição como a questão morphs enquanto estamos a tentar resolver o problema

Os atuais olhares código como:

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);
    }
    ...

Pergunta: se este está sendo executado em um servidor web, é seguro para ser usando a função strtok() thread-inseguro? Eu vou assumir 'Sim, é seguro', embora eu não estou totalmente convencido. você imprimiu a corda header? você imprimiu o valor de path? Será que você realmente pretende vazar o path alocados? Você percebe que a seqüência malloc() + strcpy() não copia BASE_DIR em path?


A versão original do código terminou com:

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

Assim, o original sugeriu resposta parcial:

Você formato em input; imprimir a partir filepath?


O que é a chance de que pontos filepath ao já lançado memória? Quando você alocar a memória, você poderia estar recebendo qualquer coisa que acontece para a área de quase-aleatória que filepath usado para apontar para. Outra possibilidade pode ser que filepath é um ponteiro para uma variável local em uma função que retornou -. Por isso aponta para algum lugar aleatório na pilha que está sendo reutilizado por outros códigos, como sprintf()

Eu também mencionado em um comentário que você pode concebivelmente precisa garantir que malloc() é declarado e verificar o valor de retorno a partir dele. O elenco '(char *)' não é obrigatória em C (é em C ++), e muitos preferem não incluir o elenco se o código é estritamente C e não bilíngüe em C e C ++.


Este código funciona para mim:

#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);
}

Produz linhas vazias estranhas mais:

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

A maneira mais fácil de descobrir o que está acontecendo é traçar através da execução em um depurador (possivelmente caindo para traçar o código de montagem).

Há alguns palpites sobre o que pode estar acontecendo:

  • corrupção de memória por outro segmento (parece improvável, se este é facilmente repetível)
  • pilha corruptos (também parece improvável, como você despejar os 2 cordas componente após a chamada malloc())
  • como mencionado por Jonathan Leffler em um comentário, você pode estar faltando um cabeçalho (talvez stdio.h) eo compilador está gerando o chamado incorreta / empilhar sequência até limpa para as chamadas printf / sprintf. Eu esperaria que você veria algumas advertências tempo de compilação se este fosse o caso -. Aqueles que você deve tomar nota de

O compilador / target você está usando?

Para fazer isso corretamente, eu alterar o código para:

/* 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;
}

Sugestões


Não há nada de errado, obviamente com o programa. ( Atualização:.. bem, há algo óbvio agora Durante a primeira hora apenas algumas linhas foram publicadas, e não tiveram erros graves ) Você vai ter que postar mais do mesmo. Aqui estão algumas idéias:

  1. malloc(3) retornos void * por isso não deve ser necessário para lançá-lo. Se você está recebendo um aviso, isso significa mais provável que você não incluiu <stdlib.h>. Se você não for, você deve. (Por exemplo, em um sistema de 64 bits, não prototipagem malloc(3) podem ser bastante graves Alguns dos ambientes de 64 bits realmente não apoiar K & R C.: -).
  2. Falando de avisos, certifique-se que você está transformando-as todas. Com gcc você pode transformar a maioria deles com -Wall.
  3. Você não está verificando o valor de retorno de malloc(3) para um erro.
  4. Use um depurador memória como elétrico da cerca . Existem muitas opções, ver o meu link.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top