C语言,一个多维数组的动态分配内存和释放内存分别在不同函数中可否?
大概情况:我在写一个程序时,需要在很多个函数中用到同一个数组(多维)的值,并且这个数组又是通过动态分配内存和赋值得到的(因为必须通过传参来确定数组每一维的长短)。例如,我...
大概情况:
我在写一个程序时,需要在很多个函数中用到同一个数组(多维)的值,并且这个数组又是通过动态分配内存和赋值得到的(因为必须通过传参来确定数组每一维的长短)。
例如,我在函数A中动态分配内存并在函数A中赋值,但考虑到在函数B和C中必须使用这个赋值过的数组,因此我没有在A中释放(free)数组内存。
想请教大虾们,我应该在何处释放内存啊?程序中的不合理地方还请大家指出
问题如下:
1,在A中申请内存并赋值后,由于在函数B、C中还要用到,是否可以等B、C函数用完这个数组了再释放内存??
2,可否理解为:释放内存这一步只需在最后调用的那个函数中做就可以了??
以下是我的程序举例
// *************************** xxx.h 文件 ************************** //
#include <stdio.h>
#include <math.h>
class Example
{
public:
double **value;
public:
void A(int num1, int num2, ...);
void B(int num1, ...);
void C(...);
};
// ************************* xxx.cpp 文件 ************************** //
#include "xxx.h"
viod Example::A(int num1, int num2, ...)
{
int i;
...
value = (double ** ) calloc (num1, sizeof(double *));
for(i=0i<num1;i++)
{
value [i] = (double * ) calloc (num2, sizeof(double ));
} // 申请动态分配内存
...// 在此函数中没有释放value内存,因为数组中的值还需在B和C中使用
}
void Example::B(int num1, ...)
{
// 此函数中没有再申明value变量,在下面表达式中直接使用
int i, j;
for(i=0;....)
{
for(j=0; ...)
value [i] [j] = ...;
}
...
// 在此函数中没有释放value内存,因为在C中还需使用
}
void Example::C
{
// C函数是最后一个使用value数组的函数,是否在这个函数最后使用free释放value数组即可?
}
// ****************************** main.cpp 文件 ****************************** //
#include "xxx.h"
int main (void)
{
int Num1, Num2;
...
Num1 = 。。。;
Num2 = 。。。;
Example _E;
_E.A(Num1, Num2, ...);
_E.B(Num1, ...);
_E.C(...);
return 0;
} 展开
我在写一个程序时,需要在很多个函数中用到同一个数组(多维)的值,并且这个数组又是通过动态分配内存和赋值得到的(因为必须通过传参来确定数组每一维的长短)。
例如,我在函数A中动态分配内存并在函数A中赋值,但考虑到在函数B和C中必须使用这个赋值过的数组,因此我没有在A中释放(free)数组内存。
想请教大虾们,我应该在何处释放内存啊?程序中的不合理地方还请大家指出
问题如下:
1,在A中申请内存并赋值后,由于在函数B、C中还要用到,是否可以等B、C函数用完这个数组了再释放内存??
2,可否理解为:释放内存这一步只需在最后调用的那个函数中做就可以了??
以下是我的程序举例
// *************************** xxx.h 文件 ************************** //
#include <stdio.h>
#include <math.h>
class Example
{
public:
double **value;
public:
void A(int num1, int num2, ...);
void B(int num1, ...);
void C(...);
};
// ************************* xxx.cpp 文件 ************************** //
#include "xxx.h"
viod Example::A(int num1, int num2, ...)
{
int i;
...
value = (double ** ) calloc (num1, sizeof(double *));
for(i=0i<num1;i++)
{
value [i] = (double * ) calloc (num2, sizeof(double ));
} // 申请动态分配内存
...// 在此函数中没有释放value内存,因为数组中的值还需在B和C中使用
}
void Example::B(int num1, ...)
{
// 此函数中没有再申明value变量,在下面表达式中直接使用
int i, j;
for(i=0;....)
{
for(j=0; ...)
value [i] [j] = ...;
}
...
// 在此函数中没有释放value内存,因为在C中还需使用
}
void Example::C
{
// C函数是最后一个使用value数组的函数,是否在这个函数最后使用free释放value数组即可?
}
// ****************************** main.cpp 文件 ****************************** //
#include "xxx.h"
int main (void)
{
int Num1, Num2;
...
Num1 = 。。。;
Num2 = 。。。;
Example _E;
_E.A(Num1, Num2, ...);
_E.B(Num1, ...);
_E.C(...);
return 0;
} 展开
5个回答
展开全部
虽然功能上这样没有问题,但这样写代码风格不太好,
建议把资源的申请与释放封装到成对的两个函数中。
比如class E中新增两个 Initial和Destory
viod Example::Initial(int num1, int num2, ...)
{
value = // 申请动态分配内存
_num1 = num1;
_num2 = num2;
}
viod Example::Destory()
{
value = // 释放所有动态内存
}
Example _E;
_E.Initial(Num1, Num2, ...);
_E.B(Num1, ...);
_E.C(...);
_E.Destory();
不要把资源的申请释放与正常的业务处理搅在一起。否则很容易出错,难以维护。(特别是大型系统中,随着业务的增加,比如以后新增一个D处理,是在C处理完后再进行一些工作,就很难维护)
世界万物,对称即美,简单即美,明确即美。:)
(一个函数中不要做两件事,特别是两件看似无关的事情,否则很难理解,而你的C似乎就做了两件不相关的事情,不明确就难理解,难维护,难扩展)
建议把资源的申请与释放封装到成对的两个函数中。
比如class E中新增两个 Initial和Destory
viod Example::Initial(int num1, int num2, ...)
{
value = // 申请动态分配内存
_num1 = num1;
_num2 = num2;
}
viod Example::Destory()
{
value = // 释放所有动态内存
}
Example _E;
_E.Initial(Num1, Num2, ...);
_E.B(Num1, ...);
_E.C(...);
_E.Destory();
不要把资源的申请释放与正常的业务处理搅在一起。否则很容易出错,难以维护。(特别是大型系统中,随着业务的增加,比如以后新增一个D处理,是在C处理完后再进行一些工作,就很难维护)
世界万物,对称即美,简单即美,明确即美。:)
(一个函数中不要做两件事,特别是两件看似无关的事情,否则很难理解,而你的C似乎就做了两件不相关的事情,不明确就难理解,难维护,难扩展)
展开全部
1,在A中申请内存并赋值后,由于在函数B、C中还要用到,是否可以等B、C函数用完这个数组了再释放内存??
可以
2,可否理解为:释放内存这一步只需在最后调用的那个函数中做就可以了??
通常不会在调用函数里面释放, 一般在destruct函数和分配内存的函数内释放, 并且在construct函数内应该把value设为NULL
viod Example::construct()
{...
value = NULL;
...
}
viod Example::A(int num1, int num2, ...)
{
...
if(value)
{
//这里释放空间
}
value = (double ** ) calloc (num1, sizeof(double *));
for(i=0i<num1;i++)
{
value [i] = (double * ) calloc (num2, sizeof(double ));
}
}
viod Example::destruct()
{...
if(value)
{
//这里释放空间
}
...
}
可以
2,可否理解为:释放内存这一步只需在最后调用的那个函数中做就可以了??
通常不会在调用函数里面释放, 一般在destruct函数和分配内存的函数内释放, 并且在construct函数内应该把value设为NULL
viod Example::construct()
{...
value = NULL;
...
}
viod Example::A(int num1, int num2, ...)
{
...
if(value)
{
//这里释放空间
}
value = (double ** ) calloc (num1, sizeof(double *));
for(i=0i<num1;i++)
{
value [i] = (double * ) calloc (num2, sizeof(double ));
}
}
viod Example::destruct()
{...
if(value)
{
//这里释放空间
}
...
}
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
用完之后再释放没有问题。
不过也不需要再C里面释放,你的double **value;是属于类的成员变量,你可以在类的析构函数里面再进行释放。或者是在下次需要重新分配新的内存的时候把旧的释放
不过也不需要再C里面释放,你的double **value;是属于类的成员变量,你可以在类的析构函数里面再进行释放。或者是在下次需要重新分配新的内存的时候把旧的释放
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
你调用完产生了一个内存空间后,不用了你就要释放掉。
比如viod Example::A(int num1, int num2, ...)里面会分配一个内存空间,则调用完后你确定后面没有用了,就释放掉。或者你可以写一个函数,把每次产生的内存在最后都能一起释放。
1,在A中申请内存并赋值后,由于在函数B、C中还要用到,是否可以等B、C函数用完这个数组了再释放内存??
是的,如果BC都要用,那等BC用完了就释放。
2,可否理解为:释放内存这一步只需在最后调用的那个函数中做就可以了??
不一定,因为产生的内存不释放在,系统是不会再分配到此区域的,所以你如果后面有函数访问的话,仍可以访问。所以你要等没有函数要用了再释放。
注意free完后,最好把产生的指针地址再赋上NULL。
比如viod Example::A(int num1, int num2, ...)里面会分配一个内存空间,则调用完后你确定后面没有用了,就释放掉。或者你可以写一个函数,把每次产生的内存在最后都能一起释放。
1,在A中申请内存并赋值后,由于在函数B、C中还要用到,是否可以等B、C函数用完这个数组了再释放内存??
是的,如果BC都要用,那等BC用完了就释放。
2,可否理解为:释放内存这一步只需在最后调用的那个函数中做就可以了??
不一定,因为产生的内存不释放在,系统是不会再分配到此区域的,所以你如果后面有函数访问的话,仍可以访问。所以你要等没有函数要用了再释放。
注意free完后,最好把产生的指针地址再赋上NULL。
追问
谢谢啊,那么对于这个例子而言,我在函数C(C是最后使用的函数)中释放内存,或者在main函数中释放,哪一种更合适呢?或者在析构函数中释放?
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
完全可以,只要保证在整个程序中分配函数用了多少次,释放函数就用多少次,要成对出现,最好在声明是初始化为NULL,用if来判断是否分配过,有条件的执行释放
这种方式很好用
这种方式很好用
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询