使用带双指针的struct及其内存构成
我编写了这段代码,其中我分配了一个结构,然后为结构释放了内存:使用带双指针的struct及其内存构成,c,pointers,struct,C,Pointers,Struct,我编写了这段代码,其中我分配了一个结构,然后为结构释放了内存: struct item { int val; int *vectOfInt; struct item *next; }; void relItem(struct item **currItem) { struct item *temp; int *intTemp; temp = *currItem; intTemp = (*currItem)->vectOfInt;
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;
}
- 如何在不使用指向结构的双指针的情况下执行相同的操作?
- 你能给我解释一下为什么要这样做,以及它是如何工作的(包括指针和双指针)?
- 我不明白一个结构是如何在主内存中表示的
(例如
;内存中的a是指向为inta[5]
数组分配的缓冲区的第一个位置的指针)a[5]
(结构项*s)
列表的值,您必须给出它的地址,因为C中的所有参数都是通过值传递的,而不是通过引用传递的
int-array[]={0,1,2,3,4,5};
-本地分配),则释放vertorOfInts
,这是无效的,并且会使程序(可能)崩溃如果不使用指向结构的双指针,我如何做同样的事情?
你必须使用双指针
你能给我解释一下为什么和如何工作(包括指针和双指针)?
双指针是必需的。数据结构是指向结构的指针。然后调用需要修改该指针的函数。由于参数是按值传递的,所以必须向指针传递指针
我不明白一个结构是如何在主内存中表示的。
通常,结构按顺序排列。因此,第一个成员将被放置在为结构保留的内存的开头,第二个成员将跟随它,依此类推。还有填充和对齐的问题,但这有点复杂,最好留给编译器处理。您可以这样想:您的数据结构是一个单链接列表,其中每个节点的类型都是
T=struct item*
。您通过列表的头部(即第一个节点)传递列表。消费者可以通过查看T来浏览整个列表。next
,值NULL
表示您已到了末尾
函数
relItem
从列表中删除第一个节点。由于它操纵列表本身,您必须向它传递一个指向列表头的指针,即T*
,即struct item**
。最后,T=NULL
将被解释(并检查!)为没有节点的空列表。此代码无需双指针即可安全运行:
无效重新项(结构项*当前项)
{…}
用relItem(列表)调用它
释放指针不会更改其值。
将双指针作为参数的函数通常用于更改指针(例如,分配指针或使其为NULL)
只要在空闲时小心(intTemp),它会崩溃,因为你正在从堆栈中释放内存。-p>你需要使用双指针,因为你需要更改指向结构的指针,而C中不允许通过引用调用 -它不能使用单个指针。因为您想更改指向对象的指针。通过语句
*currItem=(*currItem)->next代码>
为了永久地更改它,您需要使用指向它的指针。这使得您使用双指针
这样想吧:
您有一个整型变量a
,希望函数更改其值。您只需使用指向变量a
比如:
在您的例子中,您希望更改指针的值,只需将其指针传递给函数即可。(双指针)
就这么简单如果要使用函数更改某个对象的值,则必须将其指针传递给该函数。
-当你打电话给malloc时,你需要它的空间。你说你想要一个和你的结构一样大的空间。(就像你在这里做的那样,list=(struct item*)malloc(sizeof(struct item));
)和malloc分配一个和你的结构一样大的空间。若结构的大小是1字节,那个么你们有一个1字节的空间,若它是4字节,那个么你们有连续的4字节。
看,这就是结构在内存中的保存方式。
如果您声明一个结构变量或数组等,那么您的结构会像数组一样保存在内存中。第一个成员先来,然后第二个
如果你有一个结构
struct myStruct
{
int a;
float b;
char c;
};
然后记忆看起来像
a
b
c
ps:您在线路free(intTemp)上非法呼叫free代码>您正在*释放*一个未*malloc*编辑的变量。您尝试过吗?它甚至不应该工作,因为您正在对free()
进行非法调用。vectOfInt
的值是指向自动变量的指针,malloc()
尚未获取该值。当你说free(intTemp)
时,你是在该指针上调用free()
,这是非法的。你怎么能说它没有错误?您的代码没有检查错误。@David:这一点很好-由于该结构在不同的位置使用了NULL
来传达事情的结局,因此您必须在代码的不同位置检查它!(我在回答中也提到了这一点。)OP:“没有崩溃”:你运行代码了吗?@frx08“没有编译器错误和崩溃”哦,天哪。恐怕除了这个还有很多要检查的!谢谢
struct myStruct
{
int a;
float b;
char c;
};