我创建了这段代码,然后分配,然后为结构释放内存:
struct item {
int val;
int *vectOfInt;
struct item *next;
};
void relItem(struct item **currItem) {
struct item *temp;
int *intTemp;
temp = *currItem;
intTemp = (*currItem)->vectOfInt;
*currItem = (*currItem)->next;
free(temp);
free(intTemp);
}
int main() {
int array[] = {0, 1, 2, 3, 4, 5};
struct item *list = NULL;
list = (struct item*) malloc(sizeof(struct item));
list->val = 0;
list->vectOfInt = array;
list->next = NULL;
relItem(&list);
return 0;
}
编辑:评论代码:
struct item {
int val;
struct item *next;
};
void edit(struct item *currItem) {
currItem->val = 2;
}
int main() {
struct item *list = NULL;
list = (struct item*) malloc(sizeof(struct item));
list->val = 0;
list->next = NULL;
edit(list);
//list-val == 2
return 0;
}
如果不使用结构的双指针,我该如何做同样的事情?
你能解释一下为什么以及如何工作(指针和双指针)?
我不明白如何在主内存中表示结构
(例如int a[5]
;在内存中a是指向为a[5]
数组分配的缓冲区的第一个位置的指针
用ha ha指针初始化的结构的相等表示形式是什么
(struct item *s)
?
答案 0 :(得分:2)
如果不使用结构的双指针,我怎么能做同样的事情?
你必须使用双指针。
你能解释一下为什么以及如何工作(使用指针和双指针)?
双指针是必要的。您的数据结构是指向结构的指针。然后,您调用一个需要修改该指针的函数。由于参数是按值传递的,因此您必须将指针传递给指针。
我不明白如何在主内存中表示结构。
通常结构按顺序排列。因此第一个成员将被放置在为结构保留的内存的开头,第二个成员将跟随它,依此类推。填充和对齐也存在问题,但这有点复杂,最好留给编译器。
答案 1 :(得分:2)
- 您需要使用双指针,因为您需要更改指向结构的指针,并且C中不允许通过引用调用。
- 单指针不起作用。因为您想要更改指向对象的指针。你可以通过*currItem = (*currItem)->next;
语句来做到这一点
要永久地更改它,您需要使用指向它的指针。这使你使用双指针。
这样想:
你有一个整数变量a
,你希望函数改变它的值。您只需使用指向变量a
的指针调用此函数
像:
void changeTheValue(int *x)
{
*x = 7;
}
void main()
{
int a = 5;
changeTheValue(&a);
}
并且在您的情况下,您想要更改指针的值,并且只需将其指针传递给函数。(双指针) 就那么简单。 如果您想使用函数更改某些内容的值,则必须将其指针传递给该函数。
- 当你调用malloc时,你想要它的空间。并且您声明您需要一个与结构大小一样大的空间。 (就像你在这里list = (struct item*) malloc(sizeof(struct item));
所做的那样)和malloc分配一个与你的结构一样大的空间。如果结构的大小是1个字节,那么你有1个字节的空间,如果它是4,那么你有连续的4个字节。
看,这是你的结构保存在内存中的方式。
如果你声明了一个struct变量或一个数组等,那么你的结构就会像(dunno,如果它是一个好的比喻)一样保存在内存中。首先是第一个成员,然后是第二个......
说你有结构
struct myStruct
{
int a;
float b;
char c;
};
然后内存看起来像
一
B'/ P>
C
ps:你正在非法拨打免费电话free(intTemp);
你是*免费*你没有* malloc * ed的变量。
答案 2 :(得分:1)
list
(并且您想要)的值,则必须提供其地址,因为C中的所有参数都是按值传递而不是通过引用传递。一个。你没有在堆上分配(使用malloc)而是在堆栈(vertorOfInts
- 本地分配)上释放int array[] = {0, 1, 2, 3, 4, 5};
这是无效的并且会使你的程序(可能)崩溃
答案 3 :(得分:1)
您可以这样想:您的数据结构是单链表,其中每个节点都是T = struct item *
类型。您通过其头部即第一个节点传递列表。消费者可以通过查看T.next
来查看整个列表并进行迭代,值NULL
表示您已经到了最后。
函数relItem
将第一个节点从列表中删除。由于它操纵列表本身,您必须向其传递指向列表头的指针,即T*
,即struct item **
。最后,T = NULL
将被解释(并检查!)为没有节点的空列表。
答案 4 :(得分:1)
这段代码可以在没有双指针的情况下安全无声地工作:
void relItem(struct item * currItem) {...}
用relItem(list)
调用它释放指针不会改变它的值。 当您想要更改指针(例如,分配它或使其为NULL)时,通常会使用将双指针作为参数的函数。
在free(intTemp)时要小心,它崩溃是因为你从堆栈中释放内存。