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

    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];

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

有帮助吗?

解决方案

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

功能 不检查源中的任何终止零字符 - 它始终会精确复制数字字节。

这为您提供了两个选择:

  • 在您复制这些内容时为此说明:

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

  • 或复制内存后,请确保字符串以 '\0' (又名。 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]);

其他提示

buffer[8] 是一个 char, %s 等待字符串,含义 char *, , 经过 &buffer[8] 反而。您会得到细分错误,因为printf试图治疗 char 作为一个 指向char, ,这是地址(如果通过字符,则不太可能是有效的)

编辑:AS 大卫 注释,如果复制字符串与之前的值相关的起点,请不要使用固定值,而不是 &buffer[8] 利用 buffer+(2*sizeof(id)) 或者 buffer[2*sizeof(id)]

主要问题是您试图通过仅传递一个字符来打印字符串。这是因为 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’

警告不应被忽略!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top