我正在尝试创建下载网页的功能。我知道libcurl有效,但我拒绝使用它。我不喜欢为了这个功能而需要安装其他软件包的想法,所以我想创建自己的软件包。
无论如何,事情进展顺利,直到我开始因未知原因收到分段错误。所以我尽可能地减少了我的代码,以便仍然发生分段错误。然后我试着调试它。
以下代码是创建分段错误的原因:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct httpheader
{
char cache_control[21];
int unsigned long content_length;
char content_type[51];
char date[41];
char expires[41];
char last_modified[41];
char location[305];
char server[51];
int status;
char transfer_encoding[11];
};
int main (void)
{
struct httpheader headerinfo;
int buf_size = 4096;
char buf[buf_size];
strncpy(buf, "HTTP/1.1 200 OK\n", buf_size);
strncat(buf, "Date: Mon, 21 Jul 2014 20:52:38 GMT\n", buf_size);
strncat(buf, "Server: Apache\n", buf_size);
strncat(buf, "Set-Cookie: geofilter_country=US; path=/; domain=www.sony.com; expires=Mon, 14-Sep-2015 20:52:38 GMT\n", buf_size);
strncat(buf, "Accept-Ranges: bytes\n", buf_size);
strncat(buf, "Content-Length: 11978\n", buf_size);
strncat(buf, "Content-Type: text/html\n", buf_size);
// printf("1\n");
set_header(&headerinfo, &buf);
display_header(&headerinfo);
exit(0);
}
int set_header (struct httpheader *heady, char *data)
{
char *ptr1, *ptr2; // Used for string manipulation.
char **dummy;
data[12] = '\0';
heady->status = atoi(&data[9]);
data[12] = ' ';
if((ptr1 = strstr(data, "Content-Length: ")) == NULL)
heady->content_length = 0;
else
heady->content_length = strtoul(&ptr1[16], dummy, 10);
heady->content_length = 0;
strcpy(heady->date, "");
strcpy(heady->content_type, "");
strcpy(heady->cache_control, "");
strcpy(heady->expires, "");
strcpy(heady->last_modified, "");
strcpy(heady->location, "");
strcpy(heady->server, "");
strcpy(heady->transfer_encoding, "");
}
int display_header (struct httpheader *heady)
{
printf("Cache-Control : %s\n", heady->cache_control);
printf("Content-Length : %d\n", heady->content_length);
printf("Content-Type : %s\n", heady->content_type);
printf("Date : %s\n", heady->date);
printf("Expires : %s\n", heady->expires);
printf("Last-Modified : %s\n", heady->last_modified);
printf("Location : %s\n", heady->location);
printf("Server : %s\n", heady->server);
printf("Status : %d\n", heady->status);
printf("Transfer-Encoding : %s\n", heady->transfer_encoding);
}
如果您查看代码,您会发现&#39; printf&#39;被注释掉的声明。如果按原样编译代码并运行程序,则会发生分段错误。如果您取消注释&#39; printf&#39;声明,然后编译它,程序运行正常,输出正确。
请帮助我了解发生了什么。为什么缺少一个&#39; printf&#39;语句创建分段错误?
$ cat /proc/version
Linux version 3.12.22+ (dc4@dc4-arm-01) (gcc version 4.7.2 20120731 (prerelease) (crosstool-NG linaro-1.13.1+bzr2458 - Linaro GCC 2012.08) ) #691 PREEMPT Wed Jun 18 18:29:58 BST 2014
$
编辑:
感谢您收到的所有帮助,这是一个了不起的社区!无论如何,我想我的问题是,一点知识是一件危险的事情。
我对C语言的理解需要扩展。认为我可以使用一些&#39; printf&#39;调试声明显然是荒谬的(它有时会起作用,但这对我来说还不够好)。另外,我需要返回函数原型。我忘记了一次,编译没有问题,所以我不再这样做了!好吧,我回去做了。
如果crashmstr将他的评论作为答案发布,我会选择它。
答案 0 :(得分:2)
崩溃的最可能原因是代码中缺少前向声明:在声明函数之前调用函数时,编译器会假定函数的所有形式参数都是int
类型。你应该收到警告。
在main
之前添加这两行来解决此问题:
int set_header (struct httpheader *heady, char *data);
int display_header (struct httpheader *heady);
以下是您的代码的一些附加说明:
set_header(&headerinfo, &buf[0])
buf
而不使用&符号或索引strncpy
/ strncat
系列函数,因为它们是为不同目的而设计的。对于希望将这些函数与固定长度字符串一起使用的读者来说,这是误导性的。答案 1 :(得分:1)
开始
int set_header (struct httpheader *heady, char *data)
不符合
char buf[buf_size];
..
set_header(&headerinfo, &buf);
&amp; buf是char **而不是char *
你的函数原型在哪里?我希望编译器像疯了一样抱怨