我正在使用以下代码在链接列表的前面推送一个新节点。我对某些概念有些怀疑。
void push(struct node **head, int data)
{
// create a new node
struct node *new_node;
new_node = malloc(sizeof(struct node));
// add data
new_node->data = data;
// add node to front of list
new_node->next = *head;
*head = new_node;
}
当我在new_node
中将*head
的值分配给*head = new_node
,然后返回时,指针new_node
是否会被销毁,因为它是一个自动变量?
new_node
被malloc
调用分配给new_node
的内存指针在new_node
被销毁后仍然合法访问,因为它在堆上,并且是从未取消分配?
我们只是使用new_node
作为占位符来存储某个内存的地址,在我们完成任务和内容之后,我们就放手了。那么struct node
类型{{1}}是否重要,因为所有指针都只是整数,我们只是用它来存储一个内存地址。指针类型在哪里变得相关,即为什么我必须声明指针的数据类型以匹配指针的数据类型?
我可以将所有指针声明为整数,然后在使用之前显式地对它们进行类型转换,以匹配指针对象的数据类型吗?
答案 0 :(得分:2)
new_node
作为指向结构类型的指针,该结构类型包含字段data
和另一个字段next
。 void *
(或更糟糕的是,整数)不会让你这样做。编译器需要类型信息来理解像new_node->data = data;
这样的表达式。答案 1 :(得分:2)
当我在* head = new_node中将new_node的值赋给* head时,和 然后返回,指针new_node是否被破坏,因为它是一个 自动变量?
销毁的是在堆栈上分配的指针,但malloc的内存仍然存在(因此头部有效),.
内存指针应该由new_node指定,由malloc分配给它 在new_node被销毁之后调用仍然是合法的,因为它已经打开了 堆,并且从未被解除分配?
这是合法的,你可以使用它。
我们只是使用new_node作为占位符来存储地址 一些记忆,在我们完成任务和事情后,我们 放手吧。那么new_node是struct node的类型是否重要 对于所有指针只是整数,我们只是用它来存储一个 内存地址。指针类型在哪里变得相关,即为什么 我是否必须声明指针的数据类型以匹配 pointee的数据类型?
指针不是整数,它们可能大于整数而且它们没有签名。首先,您保证地址适合指针。如果你不想定义一个结构指针,你就可以使用一个空指针,但是你不能轻易地使用它(没有一个强制转换)和相同的指针。
我可以将所有指针声明为整数然后显式声明 在使用之前对它们进行类型转换,以匹配指针对象的数据类型?
不,你不能。为此目的使用void指针。
答案 2 :(得分:2)
对于所有指针都只是整数,我们只是使用它来存储内存地址。
没有!指针只是内存中的地址位置,其大小取决于编译器和使用的体系结构。语言不能保证它们是整数。
指针类型在哪里变得相关,即为什么我必须声明指针的数据类型以匹配指针对象的数据类型?
类型安全。当你指向一个字符的指针时,它将是char*
类型,但是将它转换为整数指针并写入它可能会导致内存损坏。让我举个例子
char ch = 'a';
char *cp = &ch;
int *ip = (int*) cp; // type safety lost since the pointer no longer refers to just one character
*ip = 1000; // memory to which 1000 is written to would span beyond a character's size
当编译器看到*ip = 1000
时,它无法警告您反对此损坏,因为它认为底层指针是一个整数;一个整数当然可以保持1000
,因此编译得很好;如果*cp = 1000
这个值被隐式转换为char
可保持的值,因此没有内存损坏。此外,如果您启用了警告,编译器将能够警告您这种缩小的隐式转换。 GCC吐出警告:隐式常量转换溢出。
我可以将所有指针声明为整数,然后在使用之前显式地对它们进行类型转换,以匹配指针对象的数据类型吗?
由于上述原因,你当然可以,但不是。详细了解type safety。
答案 3 :(得分:1)
When I assign the value of new_node to *head in *head = new_node, and then
return, does the pointer new_node get destroyed, as it's an automatic variable?
不,它没有。 new_node只要你释放它就会有效。由于在完成函数调用后您没有任何句柄,因此它的内存会泄漏。你无法取回它。
Should the memory pointer by new_node, assigned to it by the malloc
call still be legal to access after new_node is destroyed, as it's on the heap,
and was never de-allocated?
与第一个答案相同
We're just using the new_node as a placeholder to store an address to some
memory, and after we're done with the assignments and stuff, we let it go.
Then should it matter that new_node is of type struct node, for all pointers
are just integers, and we're just using it to store a memory address.
Where does the pointer type become relevant i.e. why do I have to declare the
data type of the pointer to match the pointee's datatype?
指针应与其指向的数据类型相同。它可能需要知道它所指向的数据的大小来管理像免费等的内存。
Can I just declare all pointers as integers and then explicitly typecast them
before using, to match the pointee's datatype?
您可以使用void指针在函数之间传输指针。