我使用的结构看起来像这样:
typedef struct {
int size; // Will be the size of *p
int *p;
} shi;
并且,对于本例,我创建了两个指向结构体的指针,shi *example
和shi 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指针被分配给example2
的p
,并且 - 先前由
(*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;