[英]Using sizeof in 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;
}
您將二進制數據的大小( sizeof
)與十六進制的文本表示的大小(您要存儲的)混淆了。
在大多數當前系統上, sizeof(int)
值為4。因此,緩沖區n3
將能夠存儲13個字符(3 * 4 + 1 == 13)。
然后,將三個整數格式化為8個字符的十六進制格式,這將需要3 * 8 + 1 == 25個字符來存儲。 導致的緩沖區溢出導致崩潰。
很明顯,當您將數據類型設置為文本格式(並自行指定字段寬度!)時,數據類型int
的大小無關緊要。
嘗試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;
}
我不太了解您的代碼中有什么sizeof
。 在concat3
,您嘗試將每個提供的整數的文本表示形式打印為8個字符的十六進制字符串:因此,所需的緩沖區大小應等於8 * 3 + 1 = 25,並且sizeof(int)
與它。
您似乎正在混合使用int占用的內存大小和它的文本表示形式的長度(在您的情況下很容易確定,因為它是由sprintf
格式字符串確定的)。
附帶說明: sprintf
是一個真正不安全的函數,您應該考慮棄用它。
之所以崩潰,是因為sizeof(int)
為4(在您的系統上很可能是4),這意味着n3
長度為13個字節。 然后,您嘗試向其寫入8 + 8 + 8 = 24個字符。
使用snprintf而不是sprintf。 想想小貓!
但是,很重要的是,您不應使用緩沖區指針創建接口,而應使用長度信息。 concat應該具有最大長度參數。 然后在里面使用snprintf。 提供給concat的長度為sizeof(n3)。
它仍然無法正常工作,但也不會崩潰。 其他答案說明了如何正確使用功能。
(哦,也不要使用gets()。僅僅因為它在標准庫中並不意味着它是好的代碼。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.