为什么动态分配 char** 和 char* 类型会使用 malloc 段错误?
Why does this dynamic allocation of type char** and char* using malloc segfault?
我不明白为什么这个代码段会出错。如果我在函数内部定义一个 char**,分配给该 char**,然后将 *commandsArray 指向该 char**,它就可以工作。有人可以解释我不理解的地方吗?提前致谢。
#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));
}
你弄错了优先级:[]
的优先级高于 *
,所以 *commandsArray[1]
访问了错误的地址。
使用括号强制计算顺序,像这样
*commandsArray = malloc(2*sizeof(char*));
(*commandsArray)[0] = malloc(30*sizeof(char));
(*commandsArray)[1] = malloc(30*sizeof(char));
或者使用临时变量来使用更具可读性的语法:
char** ret = malloc(2*sizeof(char*));
ret[0] = malloc(30*sizeof(char));
ret[1] = malloc(30*sizeof(char));
*commandsArray = ret;
注: Casting malloc
is unnecessary.
*commandsArray[1]
与 *(commandsArray[1])
相同,但您在这里想要的是 (*commandsArray)[1]
.
commandsArray[1]
是 commandsArray_var
之后的内存(就您而言,它包含垃圾),被视为 char*
.
*commandsArray[1]
尝试取消引用垃圾 char*
,这是段错误。
您需要做的就是添加括号 - 使其成为 (*commandsArray)[1]
。
这也会影响上一行,它使用 *commandsArray[0]
,但巧合的是(因为 *x == x[0]
),(*commandsArray)[0]
与 *(commandsArray[0])
相同(两者都是与 **commandsArray
相同)。无论如何,您也应该将括号添加到该行,以明确您的代码试图做什么。
*commandsArray[0]
应该是 (*commandsArray)[0]
.
此外,您 malloc 的 space 数量错误。通过使用与您正在创建的指针指向的类型相对应的 sizeof
表达式,as explained here.
可以减少犯此错误的机会
按照 dasblinkenlight 的建议使用临时指针也是一个好主意。这使得从分配失败中清理更容易,也更容易阅读你的代码:
char **new;
new = malloc( 2 * sizeof *new );
new[0] = malloc( 30 * sizeof **new );
new[1] = malloc( 30 * sizeof **new );
*commandsArray = new;
我不明白为什么这个代码段会出错。如果我在函数内部定义一个 char**,分配给该 char**,然后将 *commandsArray 指向该 char**,它就可以工作。有人可以解释我不理解的地方吗?提前致谢。
#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));
}
你弄错了优先级:[]
的优先级高于 *
,所以 *commandsArray[1]
访问了错误的地址。
使用括号强制计算顺序,像这样
*commandsArray = malloc(2*sizeof(char*));
(*commandsArray)[0] = malloc(30*sizeof(char));
(*commandsArray)[1] = malloc(30*sizeof(char));
或者使用临时变量来使用更具可读性的语法:
char** ret = malloc(2*sizeof(char*));
ret[0] = malloc(30*sizeof(char));
ret[1] = malloc(30*sizeof(char));
*commandsArray = ret;
注: Casting malloc
is unnecessary.
*commandsArray[1]
与 *(commandsArray[1])
相同,但您在这里想要的是 (*commandsArray)[1]
.
commandsArray[1]
是 commandsArray_var
之后的内存(就您而言,它包含垃圾),被视为 char*
.
*commandsArray[1]
尝试取消引用垃圾 char*
,这是段错误。
您需要做的就是添加括号 - 使其成为 (*commandsArray)[1]
。
这也会影响上一行,它使用 *commandsArray[0]
,但巧合的是(因为 *x == x[0]
),(*commandsArray)[0]
与 *(commandsArray[0])
相同(两者都是与 **commandsArray
相同)。无论如何,您也应该将括号添加到该行,以明确您的代码试图做什么。
*commandsArray[0]
应该是 (*commandsArray)[0]
.
此外,您 malloc 的 space 数量错误。通过使用与您正在创建的指针指向的类型相对应的 sizeof
表达式,as explained here.
按照 dasblinkenlight 的建议使用临时指针也是一个好主意。这使得从分配失败中清理更容易,也更容易阅读你的代码:
char **new;
new = malloc( 2 * sizeof *new );
new[0] = malloc( 30 * sizeof **new );
new[1] = malloc( 30 * sizeof **new );
*commandsArray = new;