为什么我的代码会产生分段错误?

时间:2014-07-22 17:42:33

标签: c segmentation-fault

我正在尝试创建下载网页的功能。我知道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将他的评论作为答案发布,我会选择它。

2 个答案:

答案 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系列函数,因为它们是为不同目的而设计的。对于希望将这些函数与固定长度字符串一起使用的读者来说,这是误导性的。
  • 不要忽视警告。当C编译器报告警告时,您的代码几乎肯定存在问题。

答案 1 :(得分:1)

开始

int set_header (struct httpheader *heady, char *data)

不符合

    char buf[buf_size];
..
    set_header(&headerinfo, &buf);

&amp; buf是char **而不是char *

你的函数原型在哪里?我希望编译器像疯了一样抱怨