[英]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]
是您內存空間中的隨機元素。是的,這絕對是可能的。 但你必須做得更多。
您有一個名為toto
的void
數組:
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';
你是:
tata
) - 好的tata[5]
- 好的tata[5]
未初始化並且包含 NULL 或一些垃圾*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.