如何通过指向结构的指针间接释放结构内数组中的指针并将其写入 NULL?

How to free and write to NULL a pointer in an array inside a struct, indirectly via pointer to struct?

我必须将指针指向的引用设置为 NULL。
但是函数 deleteP(...) 似乎不起作用,由输出指示。
函数 delete()memoryset() 以某种方式工作,即使后者只是用零填充内存(由数组中的指针指向)。
我希望数组中的指针最终为 NULL,但这是行不通的。

我需要通过指向结构的指针(在我的代码中是 eldeleteP(...) 中的局部指针变量来做所有事情(即将 fs->child[20] 设置为 NULL 等) ).这是因为我在 fs children 和他们的 children 上迭代了很多次,我把当前的 child 放在 el.

我该如何解决?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define HEIGHT 255
#define LENGTH 256
#define MAX_CHILDREN 1024

typedef struct FS FS;
typedef struct Elem Elem;

struct Elem {
    char name[LENGTH];
    char content[256];
    int isFile;
    int emptyCells;
    Elem *child[MAX_CHILDREN];
};

struct FS {
    int emptyCells;
    Elem *child[MAX_CHILDREN];
};

void delete(FS *fs){
    free(fs->child[20]);
    fs->child[20] = NULL;
}

void deleteP(FS *fs){
    Elem *el = calloc(1, sizeof (Elem));
    el = fs->child[20];
    free(el);
    el = NULL;
}

void memoryset(FS *fs){
    Elem *el = calloc(1, sizeof (Elem));
    el = fs->child[20];
    memset(el, 0, sizeof(Elem));
}

int main(int argc, const char * argv[]) {      

    FS *fs = calloc (1, sizeof(FS));
    fs->emptyCells = MAX_CHILDREN;
    fs->child[20] = calloc (1, sizeof(Elem));
    strcpy(fs->child[20]->name, "Hello");
    printf("No delete: %s\n", fs->child[20]->name);

    memoryset(fs);
    printf("MEMSET: %s\n", fs->child[20]->name);

    fs->child[20] = calloc (1, sizeof(Elem));
    strcpy(fs->child[20]->name, "Hello");
    delete(fs);
    printf("Delete: %s\n", fs->child[20]->name);

    fs->child[20] = calloc (1, sizeof(Elem));
    strcpy(fs->child[20]->name, "Hello");
    deleteP(fs);
    printf("DeleteP: %s\n", fs->child[20]->name);


}

输出:

No delete: Hello
MEMSET: 
Delete: (null)
DeleteP: Hello

请允许我用我的话来表达你的目标
(在聊天中验证我的理解后):

  • 你想释放存储在数组中的指针指向的内存, 它在一个结构中,你得到一个指向
  • 的指针
  • 不能直接访问数组成员,
    仅通过指向包含结构的指针
  • 你还想将 NULL 写入数组成员
  • 查看您的代码,您试图通过复制数组成员(它是一个指针)来做到这一点
  • 大部分情况下都有效,只是数组成员最终不会为 NULL (以及xing和BLUEPIXY提到的一些问题)

基本上,您需要一个指向数组成员的指针,而不是数组成员的副本。

所以你的函数应该是:

void deleteP(FS *fs){
    Elem **el; // pointer to pointer, instead of pointer (and no calloc)
    el = &(fs->child[20]); // pointer to array member
    free(*el); // free the pointer in the array member (not a copy of it),
               // though the effect is the same
    *el = NULL; // write NULL to the array member, not a copy of it,
                // this is what changes the effect to what you want 
}

如果我没有输入错误的话,这或多或少是我们聊天的结果。
据我了解,它可以解决您的问题。干杯。

据我所知,这也应该修复 xing 在 deleteP(...) 中发现的内存泄漏。
但也要注意在 memoryset(...).

中修复它

这不能解决 BLUEPIXY 发现的 UB(未定义行为)问题。 为此,您需要重新处理调试打印,并确保不要取消引用任何指向已释放内存的指针(执行顺序的问题),也不要取消引用任何设置为 NULL 的指针。

顺便说一句,这可以在没有局部指针变量的情况下完成;通过参数 fs 做所有事情。但我让解决方案更接近您自己的代码,以便更清楚地了解有什么区别。同样在我看来,您通过本地指针进行操作的方式更具可读性。它甚至可能更快,但看到现代编译器有多好,我对此表示怀疑;真正的原因是清晰度和可读性。