[英]Why does this dynamic allocation of type char** and char* using malloc segfault?
I don't understand why this code segmentation faults. 我不明白为什么这段代码分段会出错。 It can work if I define a char** inside of the function, allocate to that char**, then point *commandsArray at that char**.
如果我在函数内部定义一个char **,分配给该char **,然后将* commandsArray指向该char **,它将可以正常工作。 Can someone explain what I am not understanding?
有人可以解释我不明白的地方吗? Thanks in advance.
提前致谢。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void input_str_to_sngl_commands( char*** commandsArray );
int main()
{
char** commandsArray_var;
input_str_to_sngl_commands( &commandsArray_var );
return 0;
}
void input_str_to_sngl_commands( char*** commandsArray )
{
*commandsArray = (char**) malloc(2*sizeof(char**));
*commandsArray[0] = (char*) malloc(30*sizeof(char));
*commandsArray[1] = (char*)malloc(30*sizeof(char));
}
You got the precedence wrong: []
has higher precedence than *
, so *commandsArray[1]
accesses a wrong address. 您得到了错误的优先级:
[]
优先级高于*
,因此*commandsArray[1]
访问错误的地址。
Use parentheses to force evaluation order, like this 使用括号来强制评估顺序,如下所示
*commandsArray = malloc(2*sizeof(char*));
(*commandsArray)[0] = malloc(30*sizeof(char));
(*commandsArray)[1] = malloc(30*sizeof(char));
or use a temporary variable to use a more readable syntax: 或使用临时变量使用更易读的语法:
char** ret = malloc(2*sizeof(char*));
ret[0] = malloc(30*sizeof(char));
ret[1] = malloc(30*sizeof(char));
*commandsArray = ret;
Note: Casting malloc
is unnecessary . 注意: 不需要
malloc
转换malloc
。
*commandsArray[1]
is the same as *(commandsArray[1])
, but what you wanted here was (*commandsArray)[1]
. *commandsArray[1]
与*(commandsArray[1])
,但是您想要的是(*commandsArray)[1]
。
commandsArray[1]
is the memory after the commandsArray_var
(which contains garbage as far as you are concerned), treated as a char*
. commandsArray[1]
是commandsArray_var
数组_var(就您所关注的而言,其中包含垃圾)之后的内存,被视为char*
。
*commandsArray[1]
tries to dereference the garbage char*
, which segfaults. *commandsArray[1]
试图取消对垃圾char*
引用,这是段错误。
All you need to do is add parentheses - make it (*commandsArray)[1]
. 您所需要做的就是添加括号-使之成为
(*commandsArray)[1]
。
This also affects the previous line, which uses *commandsArray[0]
, but coincidentally (since *x == x[0]
), (*commandsArray)[0]
is the same as *(commandsArray[0])
(and both are the same as **commandsArray
). 这也会影响使用
*commandsArray[0]
的上一行,但同时发生(因为*x == x[0]
), (*commandsArray)[0]
与*(commandsArray[0])
(并且两者都相同)与**commandsArray
相同。 You should add the parentheses to that line as well anyway, to make it clear what your code is trying to do. 无论如何,您都应该在该行上加上括号,以使代码清楚地知道要做什么。
*commandsArray[0]
should be (*commandsArray)[0]
. *commandsArray[0]
应为(*commandsArray)[0]
。
Also, you malloc the wrong amount of space. 此外,您分配了错误的空间量。 The chance of making this mistake can be reduced by using a
sizeof
expression that corresponds to the type being pointed to by the pointer you are creating, as explained here . 可以通过使用
sizeof
表达式来减少犯此错误的机会,该表达式与您正在创建的指针所指向的类型相对应, 如此处所述 。
Using a temporary pointer as suggested by dasblinkenlight is a great idea too. 使用dasblinkenlight建议的临时指针也是一个好主意。 This makes it easier to clean up from allocation failure and easier to read your code:
这样可以更轻松地清除分配失败并更易于阅读代码:
char **new;
new = malloc( 2 * sizeof *new );
new[0] = malloc( 30 * sizeof **new );
new[1] = malloc( 30 * sizeof **new );
*commandsArray = new;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.