2017-03-12 49 views
-3

我有以下代码,当试图访问数组splitted时,会给我Segfault。我是否以错误的方式重新分配指针数组?重新分配指向字符的指针数组

void allocate (char** splitted) { 
    splitted = malloc(sizeof(char*)); 
    for (int i = 0; i < 3; i++) { 
     splitted = realloc(splitted, (i + 1) * sizeof(char*)); 
     splitted[i] = "asd"; 
    } 
} 

int main() { 
    char** splitted = NULL; 
    allocate(splitted); 
    for (int i = 0; i < 3; i++) { 
     printf("%s", splitted[i]); 
    } 
    return 1; 
} 
+0

试图在这样的循环中扩展'splitted'而不是在循环之前尝试'malloc'所需的大小的动机是什么? –

+0

使用'allocate'的结果,当前'void'返回新的序列地址。 – WhozCraig

+0

你没有包含任何库头文件,请不要因为你有代表而认为“我们知道你做了”。你应该更清楚。 –

回答

2

是的,你是以错误的方式重新分配你的数组 - 实际上是一些错误的方法。

你忘了splitted通过到函数。因此,对函数内部值的任何更改对调用者都是不可见的。

因此,要么改变函数添加一个额外的间接级别。

void allocate (char*** splitted) 
{ 
    *splitted = malloc(sizeof(char*)); 
    for (int i = 0; i < 3; i++) 
    { 
     *splitted = realloc(splitted, (i + 1) * sizeof(char*)); 
     (*splitted)[i] = "asd"; 
    } 
} 

/* to call it in main() */ 

allocate(&splitted); 

或将其更改为返回新值

char *allocate (char** splitted) 
{ 
    splitted = malloc(sizeof(char*)); 
    for (int i = 0; i < 3; i++) 
    { 
     splitted = realloc(splitted, (i + 1) * sizeof(char*)); 
     splitted[i] = "asd"; 
    } 
    return splitted; 
} 

/* to call it in main() */ 

splitted = allocate(splitted); 

其他一些注意事项如下。

我假设你在你的代码之前有一个#include <stdlib.h>(否则使用malloc()realloc()将不能编译)。将来,提供一个MCVE,所以试图帮助你的人不必对你遗漏的东西做出假设或猜测。

该函数中的malloc()的调用是不需要的,因为realloc()可以接受NULL

此外,realloc()不需要在循环中。循环之前将会有一个realloc() - 只提供最终的预期大小。

强烈建议检查功能的返回值,如realloc()malloc(),因为它们都可以返回错误指示。显然,如果你检查返回值,你也需要明智地处理错误。

由于您的代码使用malloc()/realloc()来分配内存,因此您还需要释放它。例如在main()的末尾free(splitted)。是的,现代操作系统清理 - 除非不是所有的系统都这么做 - 所以不使用free()是一个不好的习惯。此外,如果您重复使用代码(例如,将您的main()重命名为其他函数,并从其他函数中调用它),您将会遇到内存泄漏。