[英]Segmentation fault when using setenv (C)
這是我的代碼的一部分(其中 max 是一個浮點數):
printf("noise level found: %f\n", max);
//Put into "String"
char var[21];
sprintf(var, "%f", max);
setenv("music_sync_soundcard_noise_level",var,1);
printf("noise level written\n");
產生輸出:
noise level found: 2410965368832.000000
Segmentation fault
雖然早些時候我有一些幾乎相同的行:
printf("test finished, offset is %f\n", *offset);
//Put into "String"
char var[20];
sprintf(var, "%f", *offset);
setenv("music_sync_soundcard_offset",var,1);
哪個工作沒有問題。
//編輯:更改數組大小,遺憾的是沒有解決問題
緩沖區大小不足是未定義行為(UB)。 該 UB 可能會出現在遠離原始 UB 的地方。
通過編寫不會溢出緩沖區的代碼來改進代碼 - 無處不在,適用於所有值。
為所有max
提供足夠的緩沖
#include <float.h>
float max;
// char var[21];
char var[1 + 1+FLT_MAX_10_EXP + 1 + 6 + 1];
// - d dddddddddd dddddddddd dddddddddd dddddddd . fraction \0
sprintf(var, "%f", max);
使用snprint()
避免緩沖區溢出@R..
// sprintf(var, "%f", max);
snprintf(var, sizeof var, "%f", max);
健壯的代碼將檢查返回值:
int len = snprintf(var, sizeof var, "%f", max);
if (len < 0 || (unsigned) len >= sizeof var) Oops();
使用"%e"
來處理和很好地呈現大小浮點值
使用指數表示法來避免大緩沖區。 使用足夠的精度。
char var[1 + 1 + 1 + FLT_DECIMAL_DIG-1 + 1 + 1 + 4 + 1];
// - d . dddddddd e - expo \0
sprintf(var, sizeof var, "%.*e", FLT_DECIMAL_DIG-1, max);
永遠不要使用sprintf()
和strcpy()
的函數,它們不接受指定緩沖區大小的參數。 始終使用snprintf()
、 strlcpy()
等,並檢查返回值是否有錯誤。 這樣,如果緩沖區太小,您可以處理它,而不僅僅是假設在緩沖區末尾的隨機內存位置上亂寫不會造成任何問題。 正如@chux 指出的那樣,您正在做的事情會導致未定義的行為。 也稱為停止並着火 (HCF)情況。
另外,請注意,這不是由於setenv()
正在做的任何事情。 錯誤在於sprintf()
寫入的內容超出了您提供的緩沖區的末尾。 在sprintf()
調用之后你所做的任何事情都可能失敗。 包括簡單地從執行該sprintf()
調用的函數返回。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.