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

标签 c pointers recursion null children

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

我需要通过指向结构(在我的代码中是 eldeleteP(...) 中的局部指针变量)。这是因为我多次遍历 fs child ,然后是他们的 child ,我把当前 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 做所有事情。但我让解决方案更接近您自己的代码,以便更清楚地了解有什么区别。同样在我看来,您通过本地指针进行操作的方式更具可读性。它甚至可能更快,但看到现代编译器有多好,我对此表示怀疑;真正的原因是清晰度和可读性。

关于c - 如何通过指向结构的指针间接释放结构内数组中的指针并将其写入 NULL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45445597/

相关文章:

c - 浮点比较 `a != 0.7`

c - 验证 C 中的输入

c - 数组大小重新定义

c - 如何使用C从数据库中分配一个字符串并将其读入结构中的指针变量数组

c++ - c++ 可以创建指向从 dll 动态加载的不同类的指针数组吗?

两种递归方法的Java复杂度

arrays - 使用数组参数时出现递归 SQL Lvl 1 错误

c - 在 ';' 之前缺少 'type'

c++ - 变量中的数据不一致

python - 按值查找嵌套字典路径