这个问题的答案描述了如何分配内存并将其返回到调用函数。举了一个例子:
void someFunction (int **data) {
*data = malloc (sizeof (int));
}
void useData (int *data) {
printf ("%p", data);
}
int main () {
int *data = NULL;
someFunction (&data);
useData (data);
return 0;
}
我还想在返回调用函数之前分配值。但是,当我尝试(例如)时:
void someFunction (int **data) {
*data = malloc (2 * sizeof (int));
*data[0] = 1;
*data[1] = 1;
}
void useData (int *data) {
printf ("%p", data);
}
int main () {
int *data = NULL;
someFunction (&data);
useData (data);
return 0;
}
我收到分段错误。任何帮助,不胜感激。
你的问题在于以下语句:
*data[0] = 1;
由于优先级的工作方式(a),这实际上等效于:
*(data[0]) = 1;
而不是如您所料:
(*data)[0] = 1;
前一种变体实际上试图取消引用尚未分配的(任意)值,这就是导致崩溃的原因。您应该使用后一种形式来更明确。
在任何情况下,检查任何可能失败的调用始终是一个好主意,以免以后根据不正确的假设导致问题。您可能还需要考虑如果调用该函数两次(或更多)会发生什么 - 它目前会导致内存泄漏,因为旧内存永远不会释放。
考虑到这些要点,我将稍微修改您的函数,如下所示:
void someFunction (int **data) {
// Release old memory if any (freeing NULL is fine).
free (*data);
// Allocate new memory and initialise only if it worked.
*data = malloc (2 * sizeof (int));
if (*data != NULL) {
(*data)[0] = 1;
(*data)[1] = 1;
}
}
(a)优先顺序由标准中表达类型的出现顺序决定。例如,C11 6.5 Expressions
指出:
语法指定运算符在表达式求值中的优先级,这与该子句的主要子句的顺序相同,优先级最高。
而且,由于数组下标出现在6.5.2.1
中,而不是间接出现在6.5.3.2
中,前者将首先发生。
有时,简化指针逻辑很有帮助。
例如,在下面显示的代码中,内存的分配和初始化是使用更熟悉的int *
(而不是int **
)完成的。 然后,在分配和初始化之后,分配的内存通过int **
返回给调用方。
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#define SUCCESS 0
int SomeFunction(int **OUT_data)
{
int rCode = SUCCESS;
int *data = NULL;
errno=SUCCESS;
data = malloc(2 * sizeof(int));
if(!data)
return(errno);
data[0] = 10;
data[1] = 20;
*OUT_data = data;
return(rCode);
}
void UseData(int *data)
{
printf("Data[%p]: %d, %dn", data, data[0], data[1]);
}
int main()
{
int rCode = SUCCESS;
int *data = NULL;
rCode=SomeFunction(&data);
if(rCode)
{
fprintf(stderr, "SomeFunction() reports: %d %sn", rCode, strerror(rCode));
return(rCode);
}
UseData(data);
return(rCode);
}