簡體   English   中英

在C中使用sizeof

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM