我做了這個小碼:是否可以將一個void *賦予char **?
void *toto = malloc(8 * sizeof(char *) * 8);
char **tata = (char **)toto;
tata[5][5] = 'a'
但我有一個分段錯誤。如何將我的void *
轉換爲char **
?
我做了這個小碼:是否可以將一個void *賦予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]
是您存儲空間中的隨機元素。可以將void *
轉換爲任何指針類型。事實上,如果不是,你不能使用malloc
分配得很好,因爲它的返回值是void *
。
當然,void *
指向的內存區域必須仍然對它的使用有效,即足夠大並且正確對齊。 (在malloc
情況下,返回的內存是正確的「任何使用」對齊,至少就一個標準的C而言)
在你的代碼中的錯誤是在這裏:
tata[5][5] = 'a'
您提領指向char *
的第6個指針從malloc
ed塊開始計數,該塊未初始化。
是的,這是絕對有可能的。但你必須做更多。
您有一個名爲toto
的void
秒的數組:
void *toto = malloc(8 * sizeof(char *) * 8);
換句話說 - toto
是一個指向一塊含8 * sizeof(char *) * 8
空隙內存 - 你可能已經想到,因爲計算表明它是一個指針數組,編譯器會自己計算它。 它不會 - 什麼是編譯器看到是這樣的:
void *toto = malloc(64);
因此你會用一維「扁平化」數組,其中每個元素都是一個void
結束。
現在你投它:
char **tata = (char **)toto;
,這一切都好爲止。現在你有tata
它指向一個指向char數組的指針數組,它是未初始化的。 tata[5]
的類型是*char
。
所以,當你這樣做:
tata[5][5] = 'a';
你:
tata
) - 確定tata[5]
- 確定tata[5]
是未初始化並且包含NULL或一些ga rbage*tata[5]
第六元素 - SEGFAULT
,因爲它不是有效的指針那你必須做的是:
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 */
這將編譯並沒有段錯誤運行。
我也建議的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';
爲什麼,什麼是你想達到什麼目的? – Sadique
這只是一個測試。沒有理由,沒有其他的代碼。 –
當然有可能。你在做。你只是用未初始化的值來做它,所以崩潰是最好的情況。 – delnan