如何释放一个malloc()';d结构正确吗?
我有一个结构malloc()'d,在使用它们之后,我想释放()它,但我的程序在这里冻结了。谁能告诉我,我做错了什么 这是我的密码:如何释放一个malloc()';d结构正确吗?,c,pointers,free,malloc,C,Pointers,Free,Malloc,我有一个结构malloc()'d,在使用它们之后,我想释放()它,但我的程序在这里冻结了。谁能告诉我,我做错了什么 这是我的密码: struct data { char *filename; char *size; }; //primarypcs is a long type variable struct data *primary = (struct data *)malloc( primarypcs * sizeof( struct data ) ); mems
struct data
{
char *filename;
char *size;
};
//primarypcs is a long type variable
struct data *primary = (struct data *)malloc( primarypcs * sizeof( struct data ) );
memset( primary, 0, sizeof(struct data *) * primarypcs );
...
...
...
for ( i = 0; i < primarypcs; i++ )
{
free( primary[i].filename ); //<----my program freezes here
free( primary[i].size ); //<----or here
}
free( primary );
struct数据
{
字符*文件名;
字符*大小;
};
//primarypcs是一个长类型变量
结构数据*primary=(结构数据*)malloc(primarypcs*sizeof(结构数据));
memset(primary,0,sizeof(struct data*)*primarypcs);
...
...
...
对于(i=0;i free(primary[i].filename);//结构中的字符串是如何分配的?如果它们是静态分配给常量的,那么就不要这样释放它们,所需要的只是free(primary);
释放一些不是malloc的东西会让堆管理器心跳加速
如果字符串指针是由malloc()或calloc()设置的,这是正确的方法。您并不是在展示整个代码,其中可能会出现很多错误,但有一个错误已经很明显。行
memset( primary, 0, sizeof(struct data *) * primarypcs );
没有执行您认为它正在执行的操作。由于sizeof
中的类型错误,它没有将整个数组归零。很可能是这样
memset( primary, 0, sizeof(struct data) * primarypcs );
请注意,在sizeof
下没有*
。由于此错误,数组中的大多数指针的初始值都包含垃圾。如果在省略的代码中未将其设置为有意义的值,则对free
的调用将接收垃圾参数并失败
一般来说,为了减少这种错误的机会,最好避免在程序中提及类型名称,除非在声明中。因为问题是标记C++(即使它看起来像C),所以不可能在MalOC><代码>上删除类型转换,但否则我会说下面看起来更好。
struct data *primary = (struct data *) malloc( primarypcs * sizeof *primary );
memset( primary, 0, primarypcs * sizeof *primary );
,作为一个旁注,如果你的代码是C++的,你可以得到一个更优雅、紧凑和可移植的方式
的相同结果。
data *primary = new data[primarypcs]();
当然,在这种情况下,您必须使用适当的C++功能来代替内存,而不是<代码>免费< /COL> .< /P> < P> >用代码>自由(主)替换代码底部的for循环。
应该可以工作。这是因为您没有显式地为文件名和大小分配内存。因此尝试执行释放(主[i].filename);
或释放(主[i].size);
将调用未定义的行为
只要免费(主要)
就足够了
编辑:
这个问题已经被标记为C++。因此C++的方式是使用<代码>新< /代码>代替用户定义的类型< <代码> MalOC 。
有关new
和malloc
之间的差异,请查看
在C++中,只需编写
data *primary = new data[primarypcs](); //() for value initialization
这修复了memset中的问题,它为您带来了各种各样的问题
memset( primary, 0, sizeof(struct data) * primarypcs );
简而言之,在“主”结构的结尾处留下未初始化的内存。
如果你在C++中这样做,你(几乎可以肯定)不应该使用类似:
data *primary = new data[primarypcs]();
相反,您应该使用以下内容:
struct data {
std::string filename;
std::string size;
};
std::vector<data> primary(primarypcs);
struct数据{
std::字符串文件名;
std::字符串大小;
};
std::主要病媒(primarypcs);
在这种情况下,通常可以更简单地处理内存管理:在需要的范围内定义向量,当它超出范围时,内存将自动释放
在C++中使用数组new(比如<代码>新x[y] < /COD>)是一个更好的方法。一次(15年前),它几乎是唯一可用的工具,因此它的(勉强)使用几乎是不可避免的——但那一天已经过去了,而且自从使用它确实有一个很好的理由以来,已经过去了10年。
由于不可避免地会有关于“除了在实现类似vector的东西时”的评论,我要指出,不,即使在实现vector时,也不使用array new——您(间接地,通过分配器)使用::operator new
分配原始内存,placement new在该内存中创建对象,显式dtor调用销毁对象。正如其他人所说,您显示的代码片段中有两个明显错误的地方:
您不为刚刚分配的结构的filename
和size
成员分配内存
您的memset()
调用使用了错误的大小
您的memset()
调用可以通过以下方式简化和更正:
memset(primary, 0, primarypcs * sizeof *primary);
代码中还有一个微妙的问题:C标准不能保证所有的零位都是null指针常量(即null),因此memset()不是将指针设置为null
的正确方法
size_t i;
for (i=0; i < primarypcs; ++i) {
primary[i].filename = NULL;
primary[i].size = NULL;
}
如果需要,您可以省略与上面的sizeof*primary[i].filename
和sizeof*primary[i].size
的乘法:C保证sizeof(char)
为1。为了完整性以及filename
和size
更改类型的情况,我编写了上面的代码
另外,请注意,如果filename
是一个长度为k
的字符串,则需要(k+1)
字节,因为上面的0
(因此n==k+1
)
如果我猜猜看,您希望size
存储相应的filename
的长度?如果是这样,size
不应该是char*
而是size\u t
。但是因为我不知道您打算如何使用filename
和size
,我不确定
确保检查malloc()
的返回值。如果失败,它将返回NULL
。为了简单起见,我在上面的代码中省略了检查
你的帖子也被标记为C++,所以如果你愿意使用C++,也有一个C++解决方案。
你不能对整个数组结果进行内存设置。
size_t i;
for (i=0; i < primarypcs; ++i) {
size_t n, m;
/* get the values of n and m */
primary[i].filename = malloc(n * sizeof *primary[i].filename);
primary[i].size = malloc(m * sizeof *primary[i].size);
}
struct data *primary = calloc(primarypcs, sizeof(struct data));
for (i = 0; i < primarypcs; ++i) {
primary[i].filename = malloc(...);
primary[i].size = malloc(...);
}