【问题标题】:How can I free all instances of dynamically allocated memory in this C code如何在此 C 代码中释放所有动态分配的内存实例
【发布时间】:2021-03-27 02:14:09
【问题描述】:

我已经编写了这个 C 代码。一开始,我使用文件处理来读取文本文件并将每一行作为字符串插入到链表中。我需要在一个单独的 void 函数中释放程序中所有的内存分配情况。我怎么做?我只包含了相关的代码部分,因为它是一个相当长的程序。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdbool.h>
#include <ctype.h>



/*Node of linked list*/
typedef struct node {
    char *data;
    struct node *next;
} node;

node *start = NULL;
node *current;

typedef enum {
    not_tested, found, missed
} state;

/*Appending nodes to linked list*/
void add(char *line) {

    node *temp = (node *)malloc(sizeof(node));
    temp->data = strdup(line);
    temp->next = NULL;
    current = start;

    if (start == NULL) {
        start = temp;
    }
    else {
        while (current->next != NULL) {
            current = current->next;
        }
        current->next = temp;
    }
}

/*read text file*/
void readfile(char *filename) {
    FILE *file = fopen(filename, "r");

    if (file == NULL) {
        exit(1);
    }

    char buffer[512];

    while (fgets(buffer, sizeof(buffer), file) != NULL) {
        add(buffer);
    }

    fclose(file);
}

【问题讨论】:

  • while(start) { node *p = start; start = start-&gt;next; free(p-&gt;data); free(p); } - 假设您实际上曾经使用过这些功能,我们甚至不知道,因为您似乎没有main
  • 正如我所说,我省略了其余的代码,因为实际的程序有两百多行,而这些函数实际上只用于一个目的,即构建链表。之后,它们保持不变。

标签: c linked-list malloc strdup


【解决方案1】:

这并不完全符合您的要求,但我将向您展示如何构建一个小类来分配可以在一次调用中释放的内存块。当您有大量小块内存要分配并因此在使用后释放时,这尤其有用。

对于您的使用而言,代码似乎太多了,但请注意,这样的类可以保存在一个独立的文件中,并在每次需要时重复使用:

struct Allocator {
    void * buffer;
    size_t capacity;
    size_t usedSize;
};

struct Allocator * newAllocator(size_t initialSize) {
    struct Allocator * allocator = malloc(sizeof(*allocator));
    if (! allocator) return NULL;
    allocator->buffer = malloc(initialSize);
    if (! allocator->buffer) { free(allocator); return NULL; }
    allocator->capacity = initialSize;
    allocator->usedSize = 0;
    return allocator;
}

void freeAllocator(struct Allocator * allocator) {
    if (!allocator) return;
    if (allocator->buffer) free(allocator->buffer);
    free(allocator);
}

void * allocate(struct Allocator * allocator, size_t size) {
    if (size + allocator->usedSize > allocator->capacity) {
        while (size + allocator->usedSize > allocator->capacity) allocator->capacity *= 2;
        allocator->buffer = realloc(allocator->buffer, allocator->capacity);
    }
    void * ptr = allocator->buffer + allocator->usedSize;
    allocator->usedSize += size;
    return ptr;
}
//-------- END ALLOCATOR

struct node {
    //...
};

// How to replace a call to malloc to allocate a node :
void add(struct Allocator *allocator, char *line) {
     struct node *temp = allocate(allocator, sizeof(*temp));
    //...
}

int main()
{
    FILE *file = fopen("myfileName", "r");
    if (file == NULL) exit(1);
    
    // Allocates the buffer and as many nodes as needed 
    struct Allocator *allocator = newAllocator(1024);
    char * buffer = allocate(allocator, 512);
    while (fgets(buffer, 512, file) != NULL) {
        add(allocator, buffer);
    }
    // Free all allocated memory in a single call
    freeAllocator(allocator);
    return 0;
}

【讨论】:

  • 我是一个初学者,这似乎有点过于复杂(如果不实施,至少要理解)。我真的只有几个术语分配了内存,所以我认为保持简单,愚蠢会更好。不过,我非常感谢您花费时间和精力来给出这个答案。
  • 没问题。正如 cmets 中所说,要以更经典的方式执行此操作,您只需要循环遍历节点并像这样释放每个节点:free(node).
猜你喜欢
  • 2017-06-13
  • 1970-01-01
  • 2013-11-22
  • 2015-10-15
  • 2015-10-20
  • 2018-08-27
  • 2023-03-03
  • 2011-09-16
相关资源
最近更新 更多