asn1c:为什么我需要释放这个结构的这个成员?

sch*_*_76 0 c struct asn.1

目前我尝试了解asn1c编译器.我现在通过PDF https://lionet.info/asn1c/asn1c-usage.pdf阅读.在2.1.7节中,释放目标结构就是这样一个例子:

/*
1. Rectangle_t is defined within my_figure
*/
struct my_figure {
    Rectangle_t rect;
} *mf = ...;

/*
 * Freeing the Rectangle_t* without freeing the mf->rect area.
*/
asn_DEF_Rectangle.free_struct( &asn_DEF_Rectangle, &mf->rect,   1 /* !free */ );
Run Code Online (Sandbox Code Playgroud)

我会看到rect其中一部分struct my_figure嵌入在同一块内存中.那么,为什么我需要用该函数释放该结构?当它没有释放内存的时候,这个功能的用途是什么?

Rectangle_t的定义如下:

RectangleTest DEFINITIONS ::= BEGIN

Rectangle ::= SEQUENCE {
    height INTEGER,
    width INTEGER
}

END
Run Code Online (Sandbox Code Playgroud)

生成的标头

/*
 * Generated by asn1c-0.9.24 (http://lionet.info/asn1c)
 * From ASN.1 module "RectangleTest"
 *  found in "../Rectangle.asn1"
 */

#ifndef _Rectangle_H_
#define _Rectangle_H_


#include <asn_application.h>

/* Including external dependencies */
#include <INTEGER.h>
#include <constr_SEQUENCE.h>

#ifdef __cplusplus
extern "C" {
#endif

/* Rectangle */
typedef struct Rectangle {
    INTEGER_t    height;
    INTEGER_t    width;

    /* Context for parsing across buffer boundaries */
    asn_struct_ctx_t _asn_ctx;
} Rectangle_t;

/* Implementation */
extern asn_TYPE_descriptor_t asn_DEF_Rectangle;

#ifdef __cplusplus
}
#endif

#endif  /* _Rectangle_H_ */
#include <asn_internal.h>
Run Code Online (Sandbox Code Playgroud)

小智 5

我认为你没有正确理解自由函数是如何工作的.free获取指向您为结构分配的区域的指针,然后让操作系统知道它不再是已分配的内存部分.例如,如果您创建一个矢量结构:

typedef struct Vector2 {
    float x,y;
} Vector2; 

// Somewhere in an executing section of code for example you do this
Vector2 *vec;
vec = (Vector2*) malloc(sizeof(Vector2));
Run Code Online (Sandbox Code Playgroud)

到目前为止,正如你所说,Vector2只是内存中的顺序数据(如果你想在一个名为heap的区域中更具体).如果你能看到它,它看起来像:

HEAP-MEMORY:...... | 浮动x | 漂浮y | ...

如果你想释放一个分配的Vector2,你只需要调用自由函数传递它的指针:

free(vec);
Run Code Online (Sandbox Code Playgroud)

这是最简单的例子,因为没有必要进行必要的处理而不是调用自由函数.那是因为结构Vector2没有指针!如果结构更复杂并且有一些指针,那么在释放空洞之前,你必须释放它的所有指针.下一个示例是列表实现,其中每个节点都指向下一个节点,直到最后一个节点指向NULL.

typedef struct Node {
    int data;
    struct Node* next;
} Node;

//Returns a new node
Node* newNode(){
     Node* node = (Node*) malloc(sizeof(Node));
     node->next = NULL;
     return node;
}

//Adds new element at tail
Node* addAtTail(Node* list){
     if(list->next != NULL)
          return addAtTail(list->next);

     list->next = newNode();
     return list->next;
}
Run Code Online (Sandbox Code Playgroud)

下一个列表将如何在堆内存中?

Node* example_list = newNode();
addAtTail(example_list);
addAtTail(example_list);
addAtTail(example_list);
Run Code Online (Sandbox Code Playgroud)

此列表如下所示:A - > B - > C - > D - > NULL

这是你的记忆:

... {int data | Node*next} ... {int data | Node*next} ... {int data | Node*next} ... {int data | 节点*下一个} ...

好的.如果只调用以下代码行,你的堆内存将如何:free(example_list);example_list是"A"节点(第一个节点),因此您释放节点"A"!这就是你的堆内存现在的方式:

...... {---------自由--------} ... {int data | Node*next} ... {int data | Node*next} ... {int data | 节点*下一个} ...

所有那些你没有免费的节点会发生什么?:d

MEMORY LEAK是正确的术语.你记忆中的那些糟糕的数据没有指向它们的指针,因此它们会永远丢失在你的记忆中,只是占据了空间!在大多数应用程序中,您不会注意到任何差异,但在关键和正在进行的应用程序中,拥有无内存泄漏应用程序非常重要,因此保持代码不泄漏是非常好的做法.

也许Rectangle_t有一些指针需要以一种特殊而独特的方式释放:)我们的示例列表的特殊自由函数将是这样的:

void freeList(Node* node){
     if(node == NULL)
          return;
     free_list(node->next);
     free(node);
}
Run Code Online (Sandbox Code Playgroud)

如果你没有调用特殊函数来释放结构节点,那么就会出现内存泄漏,这就是必要的原因.我想这与Rectangle_t的原因相同