C语言 处理指向结构的指针时丢失内存字节



我使用的结构看起来像这样:

typedef struct {
    int size; // Will be the size of *p
    int *p;
} shi;

并且,对于本例,我创建了两个指向结构体的指针,shi *exampleshi example1

然后我写了3个函数,这将是这个问题的例子:

1。一个将构建结构及其*p数组的函数,看起来像这样:

void build(shi **example, shi **example2) {
    *example = malloc(sizeof(shi));
    (*example)->size = 3;
    (*example)->p = malloc((*example)->size*sizeof(int));
    
    *example2 = malloc(sizeof(shi));
    (*example2)->size = 6;
    (*example2)->p = malloc((*example2)->size*sizeof(int));
}

2。另一个将作为中介的函数。在本例中,它将只调用第三个函数:

void intermediary(shi **example, shi **example2) {
    // This is a recursive function
    // At some point, will call rebuild(), which will take one position from
    // the p array of example and put it into example2
    rebuild(example,example2);
}

3。第三个函数,将example->p的最后一个元素与example2->p的最后一个元素交换。

void rebuild(shi **example, shi **example2) {
    // Passes last position from example->p to example2->p  
    (*example2)->size++;
    (*example2)->p = realloc((*example2)->p,(*example2)->size*sizeof(int));
    // Last position of example->p = last position of example2->
    (*example2)->p[(*example2)->size-1] = (*example)->p[(*example)->size-1];
    (*example)->size--;
    (*example)->p = realloc((*example)->p,(*example)->size*sizeof(int));
}

好吧,在我的主程序中,我调用build()intermediary(),传递我的结构体的地址,它都工作得很好(编译并做它必须做的事情),所以-因为这是学校的东西-我可能会得到一个不错的分数。

问题是,只是为了知道如何把事情做好,我想让它"更好",所以我用valgrind运行了这个程序,结果出现了一堆错误。

如果你能给我一些提示,告诉我现在在做什么,或者我能做得更好,我将不胜感激。

    你可以在这里看到我为这个例子制作的完整代码。
  • 和valgrind给我的输出。

编辑

代码中有错误。新的代码在这里,新的valgrind输出在这里。

提前感谢!

当您的rebuild函数执行此操作时

(*example2)->p = realloc((*example)->p,(*example)->size*sizeof(int));
//       ^                        ^             ^
//      #2                       #1            #1

发生两件事:

  • 指针(*example)->p变得无效,因为realloc -ed指针被分配给example2p,并且
  • 先前由(*example2)->p指向的块中的数据丢失,因为您没有free()它,现在指针消失了。

我认为这是一个复制粘贴错误,你的意思是写

(*example2)->p = realloc((*example2)->p,(*example2)->size*sizeof(int));

我看到了三件事。首先,字段p是指向int的指针,但是您将它用作指向结构体shi的指针。第二件事比较次要,但应该注意。在某些计算机中,指针的大小可能大于指针的大小。在结构体中,应该把大小最大的字段放在前面。第三个最重要的事情是,对于表示malloc对象的大小,通常使用类型size_t。参见malloc()的手册页。

考虑到这些,将shi的定义改为:

#include <stdlib.h> // Look at man page for malloc()
typedef struct shi_tag {
    size_t size; // Will be the size of *p
    struct shi_tag *p;
} shi;

相关内容

  • 没有找到相关文章

最新更新