簡體   English   中英

是否可以將 void * 轉換為 char **?

[英]Is it possible to cast a void * to a char **?

我做了這個小代碼:

void  *toto = malloc(8 * sizeof(char *) * 8);
char  **tata = (char **)toto;
tata[5][5] = 'a'

但我有一個分段錯誤 如何將我的void *轉換為char **

malloc調用正在為 64 個未初始化內存指針分配空間。 然后,您使用tata作為雙間接指針。 就是這樣:

  • tata指向 64 個指針的開始。
  • tata[5]malloc d 塊的第六個元素,由於tata類型為char**tata[5]類型為char* :帶有垃圾的指針。
  • tata[5][5]是從tata[5]開始指向的第六個元素。 但是由於tata[5]是垃圾,因此tata[5][5]是您內存空間中的隨機元素。

是的,這絕對是可能的。 但你必須做得更多。

您有一個名為totovoid數組:

void *toto = malloc(8 * sizeof(char *) * 8);

換句話說 - toto是一個指向包含8 * sizeof(char *) * 8 toto值的內存的指針 - 你可能認為因為計算表明它是一個指針數組,編譯器會自己計算出來。 它不會 - 編譯器看到的是這樣的:

void *toto = malloc(64);

因此,您最終會得到一個一維“平面”數組,其中每個元素都是一個void

現在你施放它:

char  **tata = (char **)toto;

到目前為止一切都很好。 現在你有tata它指向一個指向未初始化的char 數組的指針數組。 tata[5]的類型是*char

所以當你這樣做時:

tata[5][5] = 'a';

你是:

  1. 訪問該指針數組( tata ) - 好的
  2. 訪問第 6 個(從 0 開始索引)指針tata[5] - 好的
  3. tata[5]未初始化並且包含 NULL 或一些垃圾
  4. 訪問*tata[5] - SEGFAULT第 6 個元素,因為它不是有效的指針

你必須做的是:

  • toto初始化為結果矩陣中需要的“行”數
  • 自己手動創建所有這些末端陣列

所以它看起來像這樣:

void *toto = malloc(8 * sizeof(char *)); /* assuming 8 rows */
char **tata = (char **)toto;
int i;
for (i = 0; i < 8; i++) {
  tata[i] = (char*)malloc(8 * sizeof(char)); /* assuming 8 columns */
}
tata[5][5] = 'a'; /* all is well now */

它可以在沒有 SEGFAULT 的情況下編譯和運行。

我還建議在 malloc 之前進行強制轉換並使用常量來表示行數和列數,這將為我們提供:

int num_rows = 8;
int num_cols = 8;
char **tata = (char**)malloc(num_rows * sizeof(char*));
int i;
for (i = 0; i < num_rows; i++) {
  tata[i] = (char*)malloc(num_cols * sizeof(char));
}
tata[5][5] = 'a';

可以將void *為任何指針類型。 事實上,如果不是這樣,你就不能很好地使用malloc進行分配,因為它的返回值是void *類型。

當然, void *指向的內存區域必須仍然對其使用有效,即足夠大且正確對齊。 (在malloc的情況下,返回的內存正確對齊以供“任何用途”使用,至少就標准 C 而言。)

您代碼中的錯誤在這里:

tata[5][5] = 'a'

您正在取消引用從malloc ed 塊開始計數的第 6 個指向char *指針,該指針未初始化。

暫無
暫無

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

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