簡體   English   中英

memset 對浮點數組做了什么?

[英]What is memset doing to a float array?

我最近在網上找到了一段代碼,看起來有點像這樣:

#include <stdio.h>
#include <string.h>

int main() {
    float m[10];
    memset(m, 0, 20); 
}

我還看到了一個片段,我認為它是正確的:

memset(m, 0, sizeof m); 

嘗試使用此代碼段打印出第一個示例的所有值時:

for (int i = 0; i < 20; i++) {
    printf("%f, \n", m[i]);
}

它產生一個 output 像這樣:

0.000000, 
0.000000, 
0.000000, 
0.000000, 
0.000000, 
0.000000, 
0.000000, 
0.000000, 
0.000000, 
0.000000, 
-0.000000, 
-4587372491414098149376.000000, 
-0.000013, 
0.000000, 
0.000000, 
0.000000, 
0.000000, 
0.000000, 
0.000000, 
0.000000

重新編譯時值發生變化的地方。

現在我有幾個問題:

  • 為什么 memset 可以比分配的更多寫入float -array,為什么不能使用char -array 執行此操作?
  • 為什么如此不一致?
  • 為什么將第二個值更改為memset的值例如1不會更改 output?

為什么 memset 可以比分配的更多寫入float -array,為什么不能使用char -array 執行此操作?

memset(m, 0, 20); ,正如問題最初顯示的那樣,寫入的內容不超過分配的內容。 通常, float在 C 實現中是四個字節,所以float m[10]; 分配 40 個字節和memset(m, 0, 20); 寫 20。

在新代碼中, memset(m, 0, sizeof m); m寫入盡可能多的字節,不多也不少。

如果要求memset寫更多,您可以嘗試這樣做的原因是 C 實現通常不進行安全檢查操作,而 C 標准不要求它們這樣做。

為什么如此不一致?

沒有什么不一致的。 memset將零寫入m的前 20 個字節,這是浮點零的編碼,采用float常用的格式(IEEE-754 binary32,也稱為“單精度”)。

之后的字節沒有被寫入,因此打印它們使用未初始化的數據。 C 標准說未初始化對象的值是不確定的。 一個常見的結果是程序已經使用了 memory 中的任何內容。 那可能是零,也可能是其他東西。

但是, for (int i = 0; i < 20; i++)的循環,您 go 超出了m中的 10 個元素。 那么訪問m[i]的行為不是由 C 標准定義的。 如上所述,一個常見的結果是程序訪問計算的 memory 並使用發生的任何內容。 但是,其他各種行為也是可能的,包括由於嘗試訪問未映射的 memory 或編譯器在優化期間用替代代碼替換未定義代碼而導致的崩潰。

為什么更改memset的第二個值不會更改 output?

它將取決於您將其更改為什么。 字節的某些值可能會導致float值非常小,它們仍然打印為“0.000000”。 例如,如果將字節設置為 1,使每個float中的 32 位0x01010101 ,它們表示float2.36942782761723955384693006253917004604239556833255136345174597127722672385008451101850084511018181850084511018181818

如果您使用 64 作為memset的第二個參數,則這些位將設置為0x40404040 ,它對值 3.0039215087890625 進行編碼,因此將打印“3.003922”。

Memsetfloat組沒有任何作用。 您只有一個包含 10 個浮點數的數組,並且您使用了一個覆蓋 20 個浮點數的循環,這意味着,由於 C 不檢查數組邊界……您已經從數組的末尾擴展了很遠,並將其解釋為浮點數不是。 我不會在這里重復其他答案中已經說過的內容,但是您在調整 C 對象的大小時遇到了問題。 sizeof運算符是您的朋友。 在將 arguments 傳遞給memcpymalloc等函數時使用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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