[英]Is it possible to cast a void * to a char **?
I have made this little code:我做了这个小代码:
void *toto = malloc(8 * sizeof(char *) * 8);
char **tata = (char **)toto;
tata[5][5] = 'a'
But I have a segmentation fault .但我有一个分段错误。 How can I convert my
void *
to a char **
?如何将我的
void *
转换为char **
?
The malloc
call is allocating space for 64 pointers of uninitialized memory. malloc
调用正在为 64 个未初始化内存指针分配空间。 Then, you are using tata
as a double indirection pointer.然后,您使用
tata
作为双间接指针。 That's it:就是这样:
tata
points to the start of the 64 pointers. tata
指向 64 个指针的开始。tata[5]
is the sixth element of the malloc
d block, and since tata
has type char**
, tata[5]
has type char*
: a pointer with garbage. tata[5]
是malloc
d 块的第六个元素,由于tata
类型为char**
, tata[5]
类型为char*
:带有垃圾的指针。tata[5][5]
is the sixth element pointed from the start of tata[5]
. tata[5][5]
是从tata[5]
开始指向的第六个元素。 But since tata[5]
is garbage, tata[5][5]
is a random element in your memory space.tata[5]
是垃圾,因此tata[5][5]
是您内存空间中的随机元素。Yes, it is definitely possible.是的,这绝对是可能的。 But you'll have to do more.
但你必须做得更多。
You have an array of void
s named toto
:您有一个名为
toto
的void
数组:
void *toto = malloc(8 * sizeof(char *) * 8);
In other words - toto
is a pointer to a piece of memory containing 8 * sizeof(char *) * 8
voids - you've probably thought that because computation suggests it is an array of pointers, the compiler will figure it itself.换句话说 -
toto
是一个指向包含8 * sizeof(char *) * 8
toto
值的内存的指针 - 你可能认为因为计算表明它是一个指针数组,编译器会自己计算出来。 It won't - what a compiler sees is something like this:它不会 - 编译器看到的是这样的:
void *toto = malloc(64);
therefore you'll end up with a 1-dimensional "flat" array where each element is a void
.因此,您最终会得到一个一维“平面”数组,其中每个元素都是一个
void
。
Now you cast it:现在你施放它:
char **tata = (char **)toto;
and it's all good so far.到目前为止一切都很好。 Now you have
tata
which points to an array of pointers to char arrays which is not initialized .现在你有
tata
它指向一个指向未初始化的char 数组的指针数组。 The type of tata[5]
is *char
. tata[5]
的类型是*char
。
So when you do:所以当你这样做时:
tata[5][5] = 'a';
you're:你是:
tata
) - oktata
) - 好的tata[5]
- oktata[5]
- 好的tata[5]
is not initialized and contains either NULL or some garbagetata[5]
未初始化并且包含 NULL 或一些垃圾*tata[5]
- SEGFAULT
, because it's not valid pointer*tata[5]
- SEGFAULT
第 6 个元素,因为它不是有效的指针What you must do is:你必须做的是:
toto
to how many "rows" you need in resulting matrixtoto
初始化为结果矩阵中需要的“行”数So it could look like this:所以它看起来像这样:
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 */
Which would compile and run without SEGFAULT.它可以在没有 SEGFAULT 的情况下编译和运行。
I also suggest doing the cast before malloc and using constants for numbers of rows and columns, which will give us this:我还建议在 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';
It is possible to cast void *
to any pointer type.可以将
void *
为任何指针类型。 Indeed, if it weren't you couldn't use malloc
to allocate very well, since its return value is of type void *
.事实上,如果不是这样,你就不能很好地使用
malloc
进行分配,因为它的返回值是void *
类型。
Of course the area of memory pointed to by the void *
must still be valid for its use, ie, large enough and aligned correctly.当然,
void *
指向的内存区域必须仍然对其使用有效,即足够大且正确对齐。 (In case of malloc
the returned memory is correctly aligned for “any use”, at least as far a standard C is concerned.) (在
malloc
的情况下,返回的内存正确对齐以供“任何用途”使用,至少就标准 C 而言。)
The bug in your code is here:您代码中的错误在这里:
tata[5][5] = 'a'
You are dereferencing the 6th pointer to char *
counting from the start of malloc
ed block, which is uninitialised.您正在取消引用从
malloc
ed 块开始计数的第 6 个指向char *
指针,该指针未初始化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.