2014-03-26 15 views
0

我做了這個小碼:是否可以將一個void *賦予char **?

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

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

+2

爲什麼,什麼是你想達到什麼目的? – Sadique

+1

這只是一個測試。沒有理由,沒有其他的代碼。 –

+6

當然有可能。你在做。你只是用未初始化的值來做它,所以崩潰是最好的情況。 – delnan

回答

5

malloc調用是分配64個指針的空間未初始化的內存。然後,您使用tata作爲雙重間接指針。就是這樣:

  • tata指向64個指針的開始。
  • tata[5]malloc d塊的第六元件,並且由於tata具有類型char**tata[5]已鍵入char*:垃圾的指針。
  • tata[5][5]是從tata[5]開始指向的第六個元素。但由於tata[5]是垃圾,因此tata[5][5]是您存儲空間中的隨機元素。
0

可以將void *轉換爲任何指針類型。事實上,如果不是,你不能使用malloc分配得很好,因爲它的返回值是void *

當然,void *指向的內存區域必須仍然對它的使用有效,即足夠大並且正確對齊。 (在malloc情況下,返回的內存是正確的「任何使用」對齊,至少就一個標準的C而言)

在你的代碼中的錯誤是在這裏:

tata[5][5] = 'a' 

您提領指向char *的第6個指針從malloc ed塊開始計數,該塊未初始化。

3

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

您有一個名爲totovoid秒的數組:

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'; 

你:

  1. 訪問指針數組(tata) - 確定
  2. 訪問6日(索引從0)指針tata[5] - 確定
  3. tata[5]未初始化並且包含NULL或一些ga rbage
  4. acessing的*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'; 
相關問題