c-为什么使用malloc-segfault动态分配类型char**和char*



我不明白为什么这个代码分段会出错。如果我在函数内部定义一个字符**,分配给该字符**,然后将*commandsArray指向该字符**。有人能解释一下我不明白的地方吗?提前谢谢。

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

演示。

注意:不需要铸造malloc

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

此外,您分配了错误的空间量。使用sizeof表达式可以减少犯此错误的几率,该表达式对应于您正在创建的指针所指向的类型,如下所述。

使用dasblinkenlight建议的临时指针也是一个好主意。这使得从分配失败中清理更容易,也更容易读取代码:

char **new;
new = malloc( 2 * sizeof *new );
new[0] = malloc( 30 * sizeof **new );
new[1] = malloc( 30 * sizeof **new );
*commandsArray = new;

最新更新