Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
可以在被调用函数中malloc数组,但在调用函数中释放它吗?_C - Fatal编程技术网

可以在被调用函数中malloc数组,但在调用函数中释放它吗?

可以在被调用函数中malloc数组,但在调用函数中释放它吗?,c,C,我不是C方面的专家,但我想做的是: int main(void) { double *myArray; ... myFunction(myArray); ... /* save myArray contents to file */ ... free(myArray); ... return 0; } int myFunction(double *myArray) { int len=0; ...

我不是C方面的专家,但我想做的是:

int main(void) {
    double *myArray;
    ...
    myFunction(myArray);
    ...
    /* save myArray contents to file */
    ...
    free(myArray);
    ...
    return 0;
}

int myFunction(double *myArray) {
    int len=0;
    ...
    /* compute len */
    ...
    myArray = malloc( sizeof(double) * len );
    if (myArray == NULL) 
      exit(1);
    ...
    /* populate myArray */
    ...
    return 0;
}
我想将
myArray
的内容保存在
main
内部,但在程序位于
myFunction
内部之前,我不知道所需的大小


因为我使用的是CentOS 6.2 Linux,我只能找到一个gcc版本,最高版本为4.4.6(不支持C99声明可变长度数组的功能;请参阅中“可变长度数组”下的“断开”),我一直在使用
-std=c89
进行编译。

由于
myFunction
不会更改main中的值
myArray
,它只会更改自己的副本,所以您所做的并不正确

除此之外,即使在风格上有争议也没关系。

简单的答案是否定的

您没有传回指针

使用

编辑

    poputateThis = *myArray;

    /* populate poputateThis */
    ...
    return 0;
编辑结束

    poputateThis = *myArray;

    /* populate poputateThis */
    ...
    return 0;
编辑

    poputateThis = *myArray;

    /* populate poputateThis */
    ...
    return 0;
应该简化你的工作
}作为良好设计和实践的问题(除了其他答案中指出的语法问题)只要符合您的代码库的最佳实践和透明性,这是可以的。您的函数应该被记录下来,以便调用方知道它必须自由,而且知道不分配它自己的内存。此外,考虑生成一个抽象数据类型,如:

// myarray.h
   struct myarray_t;
   int myarray_init(myarray_t* array); //int for return code
   int myarray_cleanup(myarray_t* array); // will clean up

myarray\u t
将保存一个动态指针,该指针将从调用函数中封装,尽管在
init
cleanup
函数中,它将分别分配和取消分配。

您想做的很好,但您的代码没有这样做--
main
永远看不到分配的内存
myFunction
的参数
myArray
使用函数调用中传递的值进行初始化,但此后修改它不会修改
main
中同名的其他不相关变量

在您的代码片段中,似乎
myFunction
总是返回
0
。如果是这样,那么修复代码的最明显方法就是返回
myArray
(并且不带任何参数)。然后
main
中的调用看起来像
myArray=myFunction();

如果
myFunction
实际上已经使用了它的返回值,那么您可以传入一个指向
double*
的指针,并将地址写入该指针的引用。Ed Heal的答案就是这样做的。
double**
参数通常称为“out参数”,因为它是指向函数用于存储其输出的位置的指针。在这种情况下,输出是缓冲区的地址

另一种方法是这样做:

size_t myFunction(double *myArray, size_t buf_len) {
    int len=0;
    ...
    /* compute len */
    ...
    if (buf_len < len) {
        return len;
    }
    /* populate myArray */
    ...
    return len;
}
size_t len = myFunction(NULL, 0);
// warning -- watch the case where len == 0, if that is possible
double *myArray = malloc(len * sizeof(*myArray));
if (!myArray) exit(1);
myFunction(myArray, len);
...
free(myArray);
您得到的是,调用者可以从任何方便的地方分配内存。您失去的是调用方必须编写更多的代码

有关如何使用该自由的示例,调用方可以编写:

#define SMALLSIZE 10;

void one_of_several_jobs() {
    // doesn't usually require much space, occasionally does
    double smallbuf[SMALLSIZE];
    double *buf = 0;

    size_t len = myFunction(smallbuf, SMALLSIZE);
    if (len > SMALLSIZE) {
        double *buf = malloc(len * sizeof(*buf));
        if (!buf) {
            puts("this job is too big, skipping it and moving to the next one");
            return;
        }
    } else {
        buf = smallbuf;
    }

    // use buf and len for something
    ...

    if (buf != smallbuf) free(buf);
}

在只需要一个小缓冲区的常见情况下,避免使用
malloc
通常是一种不必要的优化——这只是调用者希望在内存分配方面有发言权的一个例子。一个更紧迫的原因可能是,您的函数被编译成与调用方函数不同的dll,可能是使用了不同的编译器,并且两者没有使用兼容的
malloc/free

标题问题的答案是“是的,在许多库中它甚至是idomatic的”,但是您的实现被破坏了。是的,如果你做得对,没关系。是的,而且本质上这是
malloc
的唯一目的。如果动态存储持续时间的生存期受相应的自动存储持续时间的限制,那么就根本没有理由使用动态存储持续时间。感谢您给出的明确答案。这会改变我在
myFunction
中填充数组的方式吗?例如:
For(i=0;i@ggkmath:是的,不过您可能会发现执行
double*newArray=malloc(…)更方便
,使用
newArray
以与当前使用
myArray
相同的方式填充数组,然后编写
*myArray=newArray;
。谢谢Steve,我相信
*myArray=newArray
只是简单地调整指针,这样就只需要额外的8字节内存来完成您的注释(例如,我们暂时没有将
len
的分配内存长度增加一倍,是吗)?我一直订阅使用
malloc
(或
new
)的东西,它应该负责
免费
(或
删除
)…如果数据在堆栈上或堆上,这种原理使我们可以使用相同的函数。@ggkmath:是的,
*myArray=newArray
只是一个指针赋值。它对数组的内容没有任何作用。我想你是指
myArray\u int(myArray\t**array)
看不到您将如何分配内存。不,ADT应该包装动态分配的数据。
myarray\u t
本身将在堆栈上。哦,我明白了,那么您需要显示结构的定义以清楚地说明。@mux:
myarray\u init
将执行类似于
array->dataptr=malloc(…)
myarray_cleanup
将执行类似
免费(数组->数据ptr);
@SteveJessop是的,我现在知道了,谢谢,没有阅读完整答案,+1。