0

我正在尝试将两个整数和一个字符串复制到缓冲区并打印出缓冲区元素。我得到第三个 printf 语句的段错误:

    id = 102;
    len = 3;
    str = "working";
    memmove(buffer,&message_id,sizeof(id));
    memmove(buffer+(sizeof(id)),&len,sizeof(len));
    memmove(buffer+(2*sizeof(id)),&string, sizeof(str));

    printf("1 is: %d\n", buffer[0]);
    printf("2 is: %d\n", buffer[4]);
    printf("3 is %s\n, buffer[8])); // here is where i get the seg fault should
    be a string
    /***/
    bufer is declared as unsinged char buffer[444];

我不知道为什么这会出现段错误?

4

3 回答 3

4

buffer[8]是 a char%s等待字符串,意思是char *&buffer[8]改为通过。您会遇到分段错误,因为 printf 试图将char视为指向 char的指针,这是地址(如果传递了 char 它不太可能是有效的)

编辑:正如大卫评论的那样,如果复制字符串的起点与它之前的值有关,请不要使用固定值,而不是&buffer[8]使用buffer+(2*sizeof(id))buffer[2*sizeof(id)]

于 2011-04-28T00:22:51.290 回答
1

主要问题是您试图通过仅传递一个字符来打印字符串。这是因为buffer[8]指向char索引 8,而不是从该位置开始的字符串。因此,您需要获取 的地址buffer[8]以使其成为字符串或char*.

它出现段错误的原因是printf尝试打印从第一个字符(即字符串内容本身)给出的地址开始的字符串,这不是有效的指针。

还有一些错别字和错误。工作版本如下:

#include <stdio.h>
#include <memory.h>

int main()
{
    unsigned char buffer[444];
    int id = 102;
    int len = 3;
    char* str = "working";

    memmove(buffer,&id,sizeof(id));
    memmove(buffer+(sizeof(id)),&len,sizeof(len));
    memmove(buffer+(2*sizeof(id)), str, sizeof(str));

    printf("1 is: %d\n", buffer[0]);
    printf("2 is: %d\n", buffer[4]);
    printf("3 is %s\n", &buffer[8]);

    return 0;
}

如果你编译这个应用程序时启用了所有警告(即-Wall),你的编译器(至少 GCC 会这样)应该警告你你的错误,如下所示:

problem.c:18: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’

警告不应被忽视!

于 2011-04-28T00:46:18.233 回答
1

您的代码有几个问题,但最重要的一点是memmove()不复制字符串的空字符字节。

该函数不检查源中的任何终止空字符 - 它总是精确复制 num 个字节。

这为您提供了两种选择:

  • 在复制内容时考虑到这一点:

memmove(buffer+sizeof(id)+sizeof(len), str, strlen(str) +1);

  • 或者在复制内存之后,确保字符串在缓冲区中以'\0'(aka. ) 结尾:0

memmove(buffer+sizeof(id)+sizeof(len), str, strlen(str));

buffer[sizeof(id)+ sizeof(len) + strlen(str) + 1] = 0;

无论如何,代码现在可以工作了。另一个问题是您试图用sizeof(str). 那是错误的,你应该这样做strlen(str)。最后一件事,为了清楚和安全的目的,不要这样做2*sizeof(id)。如果以后您决定更改变量类型,那您就完蛋了。正确的方法是sizeof(id)+sizeof(len)。就这样。

int id = 102;
int len = 3;
char* str = "working";
char buffer[444];

memmove(buffer,&id,sizeof(id));
memmove(buffer+(sizeof(id)), &len, sizeof(len));
memmove(buffer+sizeof(id)+sizeof(len), str, strlen(str));
buffer[sizeof(id)+ sizeof(len) + strlen(str) + 1] = 0;

printf("1 is: %d\n", buffer[0]);
printf("2 is: %d\n", buffer[4]);
printf("3 is: %s\n", &buffer[8]);
于 2011-04-28T00:52:46.923 回答