我和我的研究生院正在尝试在redpitaya (传感器组合)上实现CNN,因此有一个有限的或没有真正的调试选项(通过UDP和LED发送一些信息)。我们在让free()正常工作时遇到了问题。问题是我们必须使用结构,并且传入的特性数量不确定。我们希望为结构中的错误和其他变量分配内存(到目前为止似乎还行)。但是,如果我们试图使用free()释放分配的内存,程序就会崩溃。我不确定如何正确传递参数(?)存储在name_t.error[i]到free()中的。我们尝试了&、*和[]的几种组合,但都不起作用。我们不是IT学生,所以这有点超出了我们的能力。
#define a
//global
struct {
...
float** error;
...
} name_t;
name_t var;
main()
init(name_t* f_var, int s1, int s2)
{
//s1 and s2 not used in the example
...
f_var->error = (float**)malloc(a*sizeof(float));
...
for(){
f_var->error[i]=(float*)malloc(b*sizeof(float));
...
}
}
//free() ?
free_func(name_t* f_var)
{
for()
{
free(f_var->error[i]);
...
}
free(f_var->error);
}
//no debugging possible!最小样本
#define a 2
//global
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
typedef struct {
int i;
float** error;
} name_t;
name_t var;
int init(name_t* f_var, int s1, int s2);
int free_func(name_t* f_var);
int main()
{
int x;
x = init(&var, 1,1);
free_func(&var);
return 0;
}
int init(name_t* f_var, int s1, int s2)
{
//s1 and s2 not used in the example
f_var->error = (float**)malloc(a*sizeof(float));
//b an array for the layersize which differs for each layer
for(int i=0; i<a;i++){
f_var->error[i]=(float*)malloc(b[i]*sizeof(float));
}
for(int j=0;j<a;j++)
{
for(int k=0;k<b;k++)
{
f_var->error[j][k]=((float)rand() / RAND_MAX - 0.5);
}
}
return 0;
}
//free() ?
int free_func(name_t* f_var)
{
for(int i=0; i<b;i++)
{
free(f_var->error[i]);
if (f_var->error[i]!=NULL)return -1;
}
free(f_var->error);
//if (f_var->error!=NULL)return -1; not needed
return 0;
}发布于 2021-04-09 20:03:54
这里有一个错误:
f_var->error = (float**)malloc(a*sizeof(float));它应该是
f_var->error = (float**)malloc(a*sizeof(float*));如果sizeof(float*)为8,则只分配所需内存的一半,从而在访问另一半内存时导致崩溃。
以下是一些提示:
sizeof *XXX,其中XXX被赋值为变量,这将在f_var->error的类型更改时有所帮助
f_var->error = malloc(a * sizeof *f_var->error);发布于 2021-04-09 20:30:39
通过使用指针数组数据结构而不是数组数组,您正在使内存分配和释放变得更慢、更大、更复杂。这不是它本身造成的问题,但是它所需要的更复杂的代码确实为错误留下了更多的空间。
您正在强制转换malloc()的返回值。这在C中不是必需的,而且它可能会掩盖错误。不要这样做。事实上,任何非算术用途的强制转换都有一些代码的味道。然而,这也不是你的问题的原因。
您没有检查分配失败。这可能与您的问题有关,但在init()中比在free_func()中更有可能导致失败。
您的f_var->error顶层分配可能分配的空间不足。这..。
f\_var->error = (float\*\*)malloc(a\*sizeof(float));
..。为float大小的a对象分配足够的空间,但您需要为这么多的float *分配空间。在许多系统上,指针都比float大,这可以解释您观察到的故障。您可以通过用接收指针的对象表示所需的大小来避免此类错误:
f_var->error = malloc(a * sizeof(*f_var->error));当然,这对于接收变量类型的更改也是有弹性的。
您的free_func假设free()会以某种方式改变作为其参数呈现的对象的值。在C中,所有的函数参数都是通过值传递的,所以free()不能改变它的参数的值,即使它想这样做。以后不能使用该值,除非它一开始就是null,特别是,除非它以前是null,否则不能期望它为null。如果你想让它为空,那么你需要自己来做。此问题将导致您的特定free_func提前终止,而不会释放所有内容。这可能会造成内存泄漏,这可能与故障有关。
假设在完整代码中,您的b确实是一个扩展为常量表达式的宏,我建议这样做:
#include <stdlib.h>
#define b 4
// ...
typedef struct {
int i;
float (*error)[b]; // array of arrays style
} name_t;
// ...
int init(name_t* f_var, int s1, int s2) {
// only one malloc needed
f_var->error = malloc(a * sizeof(*fvar->error));
if (!f_var->error) return 1; // malloc failed
for (int j = 0; j < a; j++) {
for (int k = 0; k < b; k++) {
f_var->error[j][k] = ((float)rand() / RAND_MAX - 0.5);
}
}
return 0;
}
int free_func(name_t* f_var) {
// only one free needed
free(f_var->error);
fvar->error = NULL;
return 0;
}https://stackoverflow.com/questions/67019415
复制相似问题