将字符串复制到无符号缓冲区:分段错误

发布于 2024-11-03 21:35:01 字数 554 浏览 0 评论 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];

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

i am trying to copy two integers and a character string to a buffer and print the buffer elements out. I get a seg fault for the third printf statement:

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

I dont know why this would seg fault?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

司马昭之心 2024-11-10 21:35:01

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

编辑:正如 David 所评论的,如果复制字符串的起点与其前面的值相关,请不要使用固定值,而应使用 &buffer[8] 使用buffer+(2*sizeof(id))buffer[2*sizeof(id)]

buffer[8] is a char, %s waits for string, meaning char *, pass &buffer[8] instead. You get segmentation fault because printf tries to treat a char as a pointer to char, which is address (and if a char is passed it's unlikely to be a valid one)

EDIT: as David commented, if the starting point for copying the string is related to the values before it, don't use a fixed value, instead of &buffer[8] use buffer+(2*sizeof(id)) or buffer[2*sizeof(id)]

靑春怀旧 2024-11-10 21:35:01

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

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

这为您提供了两个选择:

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

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

There were several issues on your code, but the most important point is that memmove() does not copy the null character byte of the string.

The function does not check for any terminating null character in source - it always copies exactly num bytes.

This gives you two options:

  • Account for that while you are copying the stuff:

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

  • Or after the memory was copied, make sure the string ends with a '\0' (aka. 0) on your buffer:

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

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

Anyway, the code works now. Another issue was that you were trying to specify the length of the string with sizeof(str). That's wrong, and you should be doing strlen(str). One last thing, for clarity and security purposes don't do 2*sizeof(id). If later you decide to change the variable type you are screwed. The right way wold be sizeof(id)+sizeof(len). That's all.

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]);
原来分手还会想你 2024-11-10 21:35:01

主要问题是您试图通过仅传递一个字符来打印字符串。这是因为 buffer[8] 引用索引 8 处的 char,而不是从该位置开始的字符串。因此,您需要获取 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’

警告不应该被忽视!

The main problem is that you are trying to print the string by passing only a character. This is because buffer[8] refers to the char at index 8, not the string starting at that position. So you need to take the address of buffer[8] to make it a string or char*.

The reason why it segfaults is that printf attempts to print a string starting at the address given by the first char (ie. the string contents itself), which is not a valid pointer.

There are also number of typos and mistakes. A working version is below:

#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;
}

If you had compiled this app with all warnings enabled (ie. -Wall), your compiler (at least GCC does) should warn you about your mistake like this:

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

Warnings should not be ignored!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文