2011-04-28 26 views
0

我试图将两个整数和一个字符串复制到一个缓冲区并打印出缓冲区元素。我得到第三个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]; 

我不知道为什么这会seg故障?

+0

什么是有两个“F”缓冲声明 - 你说的是BUFER无符号的字符[444] – Hogan 2011-04-28 00:21:09

+0

如何为*串*和*海峡*宣告? – karlphillip 2011-04-28 00:23:43

回答

1

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

The function不检查源中的任何终止空字符 - 它始终复制完整的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]); 
+0

很好的解释。非常感谢。我忘了使用strlen并且说明了空字符 – Warz 2011-04-28 16:24:28

4

buffer[8]char,%s等待字符串,意思是char *,代之以通过&buffer[8]。你得到分段错误,因为printf的尝试治疗焦炭字符指针,这是地址(如果一个char传递它不可能是一个有效的)

编辑:大卫评论,如果复制字符串的起点是与之前的值,不使用的,而不是&buffer[8]使用buffer+(2*sizeof(id))buffer[2*sizeof(id)]

+0

+1,虽然'缓存+ 8'或更好的'缓冲区+ 2 * sizeof(int)'是更可取的 – 2011-04-28 00:59:32

+0

@David - 你是对的,感谢评论。 – MByD 2011-04-28 01:01:44

1

的主要问题一个固定值,是您正在试图通过传递给打印字符串只有一个角色。这是因为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; 
} 

如果你在编译这个应用程序启用了,你的编译器(至少GCC一样)应该提醒你注意你的错误是这样所有的警告(即-Wall):

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

警告不应忽视!

相关问题