在C中使用sizeof

时间:2010-11-11 13:26:06

标签: c++ c

我正在使用以下程序,该程序正在崩溃。有人知道它崩溃的原因吗?

/* writes a, b, c into dst 
** dst must have enough space for the result 
** assumes all 3 numbers are positive */ 
void concat3(char *dst, int a, int b, int c) { 
    sprintf(dst, "%08x%08x%08x", a, b, c); 
} 

/* usage */ 
int main(void) { 
    printf("The size of int is %d \n", sizeof(int));
    char n3[3 * sizeof(int) + 1]; 
    concat3(n3, 0xDEADFACE, 0xF00BA4, 42); 
    printf("result is 0x%s\n", n3); 
    return 0; 
} 

5 个答案:

答案 0 :(得分:13)

你混淆二进制数据的大小(这是sizeof)给你的大小,以及十六进制的文本表示的大小,这就是你想要存储的内容。

在大多数当前系统上,sizeof(int)的计算结果为4.因此,缓冲区n3将能够存储13个字符(3 * 4 + 1 == 13)。

然后,将三个整数格式化为8个字符的十六进制格式,这需要存储3 * 8 + 1 == 25个字符。结果缓冲区溢出导致崩溃。

当您将其格式化为文本(并自行指定字段宽度!)时,显然数据类型int的大小无关紧要。

答案 1 :(得分:2)

尝试3*2*sizeof(int)+1,其中2*sizeof(int)是打印每个字节值int所需的字节数,以十六进制表示。当然,由于您使用的是%08X格式并期望固定宽度的结果,因此您应该使用uint32_t。顺便说一下,你的程序也错误地将0xDEADBEEF作为int传递给了它可能不适合的#include <inttypes.h> #include <stdio.h> /* writes a, b, c into dst ** dst must have enough space for the result ** assumes all 3 numbers are positive */ void concat3(char *dst, uint32_t a, uint32_t b, uint32_t c) { sprintf(dst, "%08"PRIX32"%08"PRIX32"%08"PRIX32, a, b, c); } /* usage */ int main(void) { printf("The size of int is %d \n", sizeof(int)); char n3[25]; concat3(n3, 0xDEADFACE, 0xF00BA4, 42); printf("result is 0x%s\n", n3); return 0; } ,从而进入了实现定义的转换为签名类型的领域。

以下是包含这些更正的版本:

{{1}}

答案 2 :(得分:1)

我真的不明白sizeof在您的代码中有什么要做的。在concat3中,您尝试将每个提供的整数的文本表示形式打印为8个字符的十六进制字符串:因此所需的缓冲区大小应等于8 * 3 + 1 = 25,sizeof(int)与此无关。

你好像用int混合了内存中占用的大小,以及它的文本表示的长度(在你的情况下很容易确定,因为它是由sprintf格式字符串修复的)。

旁注:sprintf是一个真正不安全的功能,您应该考虑弃用。

答案 3 :(得分:0)

崩溃是因为sizeof(int)(最有可能在您的系统上)4,这意味着n3长度为13个字节。然后你尝试写8 + 8 + 8 = 24个字符。

答案 4 :(得分:0)

使用snprintf代替sprintf。想想小猫!

但严重的是,您不应该使用缓冲区指针创建接口,而不能创建长度信息。 concat应该有一个最大长度参数。然后在里面使用snprintf。给concat的长度是sizeof(n3)。

它仍然无效,但也不会崩溃。其他答案解释了如何使功能正确。

(哦,也不要使用gets()。只是因为它在标准库中并不意味着它是好的代码。)

相关问题