是否有可能将空*转换为char **?

时间:2014-03-26 09:39:05

标签: c pointers void

我已经制作了这个小代码:

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

但我有一个分段错误。如何将void *转换为char **

3 个答案:

答案 0 :(得分: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]是您的内存空间中的随机元素。

答案 1 :(得分:3)

是的,这绝对是可能的。但你必须做更多。

您有一个名为void的{​​{1}}数组:

toto

换句话说 - void *toto = malloc(8 * sizeof(char *) * 8); 是指向包含toto个空洞的内存的指针 - 您可能认为因为计算建议它是一个指针数组,编译器会自己解决它。 它不会 - 编译器看到的是这样的:

8 * sizeof(char *) * 8

因此,您最终会得到一个“平面”数组,其中每个元素都是void *toto = malloc(64);

现在你施展它:

void
到目前为止,这一切都很好。现在你有char **tata = (char **)toto; 指向char数组的指针数组,未初始化tata的类型为tata[5]

所以当你这样做时:

*char

你:

  1. 访问指针数组(tata[5][5] = 'a'; ) - 确定
  2. 访问第6个(从0索引)指针tata - 确定
  3. tata[5] 未初始化并且包含NULL或一些垃圾
  4. 访问tata[5] - *tata[5]的第6个元素,因为它不是有效指针
  5. 你必须做的是:

    • SEGFAULT初始化为矩阵所需的“行数”
    • 自己手动创建所有这些结束阵列

    所以看起来像这样:

    toto

    在没有SEGFAULT的情况下编译和运行。

    我还建议在malloc之前进行强制转换,并使用常量来表示行数和列数,这样就可以了:

    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 */
    

答案 2 :(得分:0)

可以将void *转换为任何指针类型。实际上,如果它不能很好地使用malloc进行分配,因为它的返回值是void *类型。

当然void *指向的内存区域仍然必须对其使用有效,即足够大并且正确对齐。 (如果malloc返回的内存已正确对齐“任何用途”,至少就标准C而言。)

您的代码中存在错误:

tata[5][5] = 'a'

您正在取消引用char *的第6个指针,从malloc ed块的开头开始计算,该块未经初始化。