首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >sprintf()变得疯狂

sprintf()变得疯狂
EN

Stack Overflow用户
提问于 2009-09-13 17:40:03
回答 8查看 2.3K关注 0票数 1

在这方面我需要一些帮助,因为这让我在C程序中感到困惑

我有两个字符串(base和path)

代码语言:javascript
复制
BASE: /home/steve/cps730
PATH: /page2.html

在我调用sprintf将它们的内容连接在一起之前,printf就是这样读的。以下是代码块

代码语言:javascript
复制
        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);

现在,您可以解释一下最终的printf语句是如何返回的吗

代码语言:javascript
复制
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

因为它根本不理解它。

**我在malloc语句中添加了9000,以防止程序崩溃(因为字符串的大小显然大于31个字节。

完整输出

代码语言:javascript
复制
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...................All使用这些变量的代码

代码语言:javascript
复制
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;
}
EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2009-09-13 18:17:06

您使用无效的指针path调用readPage -它指向先前使用method指针分配的内存,该指针在调用readPage之前被释放。下一个malloc可以重用这个内存,然后任何事情都可能发生。

票数 6
EN

Stack Overflow用户

发布于 2009-09-13 17:51:31

好吧,显然这是不可能的:-)

我的猜测是你的堆已经被严重损坏了。

我将查看filepath、input和base使用的实际指针值。我想知道您是否会发现输入非常接近filepath?

我还会看看filepath,base等最初是如何创建的,你会不会有缓冲区溢出?

票数 4
EN

Stack Overflow用户

发布于 2009-09-13 17:48:10

啊--当我们试图解决问题时,随着问题的变化,追逐的激动人心!

当前代码如下所示:

代码语言:javascript
复制
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);
    }
    ...

问:如果这是在web服务器上运行的,那么使用线程不安全的函数strtok()安全吗?我会假设‘是的,它是安全的’,尽管我并不完全信服。你打印header字符串了吗?你打印出path的值了吗?你真的打算泄露分配的path吗?您是否意识到malloc() + strcpy()序列不会将BASE_DIR复制到path

代码的原始版本以:

代码语言:javascript
复制
 printf("\n\nPATH: %s\n\n", filepath);

因此,最初的建议部分答案是:

你格式化成input;你从filepath打印吗?

filepath指向已经释放的内存的可能性有多大?当你分配内存时,你可能会得到filepath曾经指向的准随机区域发生的任何事情。另一种可能是,filepath是指向已返回的函数中的局部变量的指针-因此它指向堆栈中被其他代码重用的随机位置,如sprintf()

我还在评论中提到,您可能需要确保声明了malloc()并检查它的返回值。'(char *)‘类型转换在C中不是强制的(它是在C++中的),如果代码严格地是C语言的,并且在C和C++中不是双语的,很多人倾向于不包括类型转换。

下面的代码适用于我:

代码语言:javascript
复制
#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);
}

它会生成无关的空行,外加:

代码语言:javascript
复制
Alloc: 31
BASE: /home/steve/cps730
PATH: /page2.html
PATH: /page2.html
PATH: /home/steve/cps730/page2.html
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1418339

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档