首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在一个struct (两个分配)C中使用free()表示float**

在一个struct (两个分配)C中使用free()表示float**
EN

Stack Overflow用户
提问于 2021-04-09 18:28:32
回答 2查看 63关注 0票数 1

我和我的研究生院正在尝试在redpitaya (传感器组合)上实现CNN,因此有一个有限的或没有真正的调试选项(通过UDP和LED发送一些信息)。我们在让free()正常工作时遇到了问题。问题是我们必须使用结构,并且传入的特性数量不确定。我们希望为结构中的错误和其他变量分配内存(到目前为止似乎还行)。但是,如果我们试图使用free()释放分配的内存,程序就会崩溃。我不确定如何正确传递参数(?)存储在name_t.error[i]free()中的。我们尝试了&*[]的几种组合,但都不起作用。我们不是IT学生,所以这有点超出了我们的能力。

代码语言:javascript
复制
#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!

最小样本

代码语言:javascript
复制
#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;
}
EN

回答 2

Stack Overflow用户

发布于 2021-04-09 20:03:54

这里有一个错误:

代码语言:javascript
复制
f_var->error = (float**)malloc(a*sizeof(float));

它应该是

代码语言:javascript
复制
f_var->error = (float**)malloc(a*sizeof(float*));

如果sizeof(float*)为8,则只分配所需内存的一半,从而在访问另一半内存时导致崩溃。

以下是一些提示:

  • 不强制转换malloc()的结果
  • 使用sizeof *XXX,其中XXX被赋值为变量,这将在f_var->error的类型更改

时有所帮助

代码语言:javascript
复制
f_var->error = malloc(a * sizeof *f_var->error);
票数 2
EN

Stack Overflow用户

发布于 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大,这可以解释您观察到的故障。您可以通过用接收指针的对象表示所需的大小来避免此类错误:

代码语言:javascript
复制
    f_var->error = malloc(a * sizeof(*f_var->error));

当然,这对于接收变量类型的更改也是有弹性的。

您的free_func假设free()会以某种方式改变作为其参数呈现的对象的值。在C中,所有的函数参数都是通过值传递的,所以free()不能改变它的参数的值,即使它想这样做。以后不能使用该值,除非它一开始就是null,特别是,除非它以前是null,否则不能期望它为null。如果你想让它为空,那么你需要自己来做。此问题将导致您的特定free_func提前终止,而不会释放所有内容。这可能会造成内存泄漏,这可能与故障有关。

假设在完整代码中,您的b确实是一个扩展为常量表达式的宏,我建议这样做:

代码语言:javascript
复制
#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;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67019415

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档