简体   繁体   English

为什么使用malloc segfault进行char **和char *类型的动态分配?

[英]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;

Demo. 演示。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM