在这方面我需要一些帮助,因为这让我在C程序中感到困惑
我有两个字符串(base和path)
BASE: /home/steve/cps730
PATH: /page2.html在我调用sprintf将它们的内容连接在一起之前,printf就是这样读的。以下是代码块
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语句是如何返回的吗
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个字节。
完整输出
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: closeEDIT...................All使用这些变量的代码
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;
}发布于 2009-09-13 18:17:06
您使用无效的指针path调用readPage -它指向先前使用method指针分配的内存,该指针在调用readPage之前被释放。下一个malloc可以重用这个内存,然后任何事情都可能发生。
发布于 2009-09-13 17:51:31
好吧,显然这是不可能的:-)
我的猜测是你的堆已经被严重损坏了。
我将查看filepath、input和base使用的实际指针值。我想知道您是否会发现输入非常接近filepath?
我还会看看filepath,base等最初是如何创建的,你会不会有缓冲区溢出?
发布于 2009-09-13 17:48:10
啊--当我们试图解决问题时,随着问题的变化,追逐的激动人心!
当前代码如下所示:
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中
代码的原始版本以:
printf("\n\nPATH: %s\n\n", filepath);因此,最初的建议部分答案是:
你格式化成
input;你从filepath打印吗?
filepath指向已经释放的内存的可能性有多大?当你分配内存时,你可能会得到filepath曾经指向的准随机区域发生的任何事情。另一种可能是,filepath是指向已返回的函数中的局部变量的指针-因此它指向堆栈中被其他代码重用的随机位置,如sprintf()。
我还在评论中提到,您可能需要确保声明了malloc()并检查它的返回值。'(char *)‘类型转换在C中不是强制的(它是在C++中的),如果代码严格地是C语言的,并且在C和C++中不是双语的,很多人倾向于不包括类型转换。
下面的代码适用于我:
#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);
}它会生成无关的空行,外加:
Alloc: 31
BASE: /home/steve/cps730
PATH: /page2.html
PATH: /page2.html
PATH: /home/steve/cps730/page2.htmlhttps://stackoverflow.com/questions/1418339
复制相似问题