iT邦幫忙

2024 iThome 鐵人賽

DAY 11
0
Software Development

RISC-V 與處理器之架構學習及應用系列 第 11

[Day11] 檔案與目錄的創建與資料保護

  • 分享至 

  • xImage
  •  

假設你被分配到用 C 語言編寫一個檔案系統。struct file_item 代表一個檔案或目錄。data union可以包含檔案的內容(作為字串)或一個指向子 file_item 的指標陣列。針對這個問題,假設指標的長度為 4 個位元組。

#include <stdbool.h>
typedef struct file_item {
    char *name;
    bool is_directory;
    file_item_data data;
} file_item;

typedef union file_item_data {
    char contents[X];
    struct file_item *children[16];
} file_item_data;

/* Copies all characters from src to dest including the NULL terminator */
char *strcpy(char *dest, const char *src);

程式碼解析

  1. typedef struct file_item:
    • 這段程式碼定義了一個名為 file_item 的結構體,這個結構體用來表示一個檔案或目錄。
    • 成員包括:
      • char *name;:儲存檔案或目錄的名稱,為一個指向字串的指標。
      • bool is_directory;:表示該項目是否為目錄。如果是目錄,則為 true;如果是檔案,則為 false
      • file_item_data data;:是一個 union 類型,根據 is_directory 的值,決定是儲存檔案的內容還是子目錄指標。
  2. typedef union file_item_data:
    • union file_item_data 根據檔案類型儲存不同的資料:
      • char contents[X];:如果該項目是檔案,則 contents 儲存檔案的內容,X 代表內容的大小(未指定大小,可能要根據實際需求定義)。
      • struct file_item *children[16];:如果該項目是目錄,則 children 會存放指向其他 file_item 結構體的指標,這些指標代表目錄下的子項目。最多可以包含 16 個子項目。
  3. strcpy 函式:
    • strcpy 是一個標準函式,目的是將來源字串 src 複製到目標字串 dest 中。它會將字串的所有字元,包括結尾的 NULL 終止符,一併複製到 dest

問題

我們將 X 設定為不增加 union 大小的最大值。那麼,我們可以在單一檔案中儲存的字串最大長度是多少呢?

B01 = 63

union 的大小由其最大的元素決定,忽略對齊規則(這裡不考慮)。在 32 位系統中,指標是 32 位(4 個位元組)。children 是一個包含 16 個指標的陣列,佔用的空間為 16 × 4 = 64 位元組。因此,我們必須確保 char contents[X] 不超過 64 位元組。由於 1 個位元組被定義為 char 的大小,將 X 設定為 64 可以達到我們的目標。結果,strlen(contents) 會返回 63,因為它不計算字串長度中的結束符號。


撰寫程式碼來建立檔案和目錄。確保即使輸入的字串在稍後被釋放,你的程式碼仍然能夠正常運作。假設輸入的字串可以適當地放入 file_item_data union 中。

/* Creates a file with the given name and contents,
 * and returns a pointer to that file.
 */
file_item *create_file(char *contents, const char *name)
{
    file_item *new_file = calloc(1, sizeof(file_item));
    new_file->name = name;
    B02 /* Fill your code here */ ;
    return new_file;
}

/* Creates a directory with the given name and no children,
 * and returns a pointer to that directory.
 */
file_item *create_directory(const char *name)
{
    file_item *new_dir = calloc(1, sizeof(file_item));
    new_dir->name = name;
    B03 /* Fill your code here */ ;
    return new_dir;
}

程式碼解析

一、file_item *create_file(char *contents, const char *name)

  1. file_item *create_file(char *contents, const char *name):

    • 這是創建檔案的函式,接受兩個參數:contents 是檔案的內容,name 是檔案名稱。
  2. file_item *new_file = calloc(1, sizeof(file_item));:

    • 使用 calloc 函數分配記憶體來創建一個 file_item 結構體,並初始化為 0。calloc 分配的記憶體會自動初始化為 0,確保結構中的成員變數在分配後不含垃圾值。
  3. new_file->name = name;:

    • 將檔案的名稱設定為傳入的 name 參數值,這樣檔案物件的 name 成員變數就會儲存檔案名稱。
  4. B02 /* Fill your code here */:

    • 這是一個佔位符,提示你要在這裡編寫程式碼以填入檔案的內容。
    • 正確的操作是將 contents 複製到 new_file->data.contents,如:
      strcpy(new_file->data.contents, contents);
      
  5. return new_file;:

    • 返回創建的 file_item 結構,代表新檔案。

二、file_item *create_directory(const char *name)

  1. file_item *create_directory(const char *name):

    • 這是創建目錄的函式,接受一個參數:name 是目錄名稱。
  2. file_item *new_dir = calloc(1, sizeof(file_item));:

    • 使用 calloc 函數分配記憶體來創建一個 file_item 結構體,並初始化為 0。這會確保新建的目錄在其初始化過程中是乾淨的。
  3. new_dir->name = name;:

    • 將目錄的名稱設定為傳入的 name 參數值,這樣目錄物件的 name 成員變數就會儲存目錄名稱。
  4. B03 /* Fill your code here */:

    • 這是一個佔位符,提示你在此填寫目錄的相關內容。
    • 正確的操作是設定該 file_item 物件為目錄,並確保 children 成員已初始化。如:
      new_dir->is_directory = true;
      
  5. return new_dir;:

    • 返回創建的 file_item 結構,代表新目錄。

問題

你的解決方案應該是完全正確的,不能有任何記憶體洩漏,並且不應包含任何額外的行。

B02 = strcpy(new_file->data.contents, contents) (or equivalent statement)

  • 在這段程式碼中,strcpy(new_file->data.contents, contents)contents 的內容複製到新檔案物件的 data.contents 中。
  • 使用 strcpy 確保將傳入的檔案內容完整地複製到 new_file->data.contents 中,這樣即使之後原始的 contents 被釋放,檔案內容仍會保持不變。
  • 這樣做是正確的,因為它防止了檔案內容丟失或引用無效記憶體,且避免了記憶體洩漏。
    B03 = new_dir->is_directory = true (or equivalent statement)
  • 這段程式碼將 new_dir->is_directory 設定為 true,這表示該 file_item 是一個目錄,而不是檔案。
  • is_directory 是一個布林變數,必須設定為 true 以明確標示該物件是目錄而不是檔案。
  • 這樣做可以讓程式正確區分目錄和檔案,避免錯誤地處理不同類型的 file_item

這兩個部分都是必需的,分別負責複製檔案內容和標示目錄類型,確保程式正確地運作,且不會有記憶體問題。


上一篇
[Day10] 使用 RISC-V 處理器的校驗碼與資料儲存實作:應用 Hamming Code 保護資料
下一篇
[Day12] 從定點到浮點的位元表示與數字範圍
系列文
RISC-V 與處理器之架構學習及應用30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言