簡體   English   中英

將字符串文字復制到 uint32_t 數組並訪問它

[英]Copying a string literal to an uint32_t array and accessing it

我在其他地方粘貼了下面的代碼,但它被認為是一個糟糕的解決方案。 該標准對 memcpy 有這樣的說法:

“memcpy 函數將 n 個字符從 s2 指向的對象復制到 s1 指向的對象中。如果復制發生在重疊的對象之間,則行為未定義。”

關於 uint32_t:

“typedef 名稱 uintN_t 指定寬度為 N 且沒有填充位的無符號整數類型。因此,uint24_t 表示寬度正好為 24 位的無符號整數類型。”

是否有任何對齊問題? 我一直在 linux 上使用它,從未遇到過任何錯誤等。 當我不得不擔心字節順序時,我只使用按位操作進行訪問,例如通過來自另一個架構的鏈接接收數據。 請放一些光。

#include <stdio.h>
 #include<string.h>
 #include<stdint.h>
 char* pointer = "HelloWorld!Hell!";
 uint32_t arr[4];
 unsigned char myArray[16];
 int main(void) {
     memcpy(arr, pointer, (size_t)16);

     // Is this illegal ? 
     char *arr1 = (char *)arr;

     for(int i = 0 ; i < 16; i++)
     {
         printf("arr[%d]=%c\n", i, arr1[i]);
     }
 }

memcpy的調用很好。 您有未定義行為的地方在這里:

printf("%s\n", arr);

%s格式說明符需要一個char *參數,但您傳遞的是uint32_t * 這種參數不匹配是未定義的行為。 這兩種指針類型在您的系統上可能具有相同的表示形式,但通常情況下不一定如此。

即使類型匹配,您仍然會有 UB,因為arr不夠大,無法包含字符串"HelloWorld!Hell!" . 這個字符串(包括空終止字節)是 17 個字節寬,因此空終止符不會被復制。 然后printf讀取數組的末尾,即 UB。

例如,我修改了變量列表如下:

 uint32_t x = 0x11223344;
 uint32_t arr[4] = { 1, 2, 3, 4 };
 uint32_t y = 0x55667788;

並得到以下輸出:

HelloWorld!Hell!�wfU

至於這個:

char *arr1 = (char *)arr;

這是合法的,因為一種對象類型的指針可以轉換為指向另一種對象類型的指針。 此外,由於目標類型是char * ,因此取消引用該指針以訪問原始對象的底層字節是合法的。

暫無
暫無

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

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