如何解决为什么地址不同但仍指向相同的数据?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node {
int data;
struct node * next;
};
int main() {
struct node * head = (struct node * ) malloc(sizeof(struct node));
head -> data = 10;
head -> next = (struct node * ) malloc(sizeof(struct node));
head -> next -> data = 20;
head -> next -> next = NULL;
int noOfNodes = 2;
char * buff = malloc(50);
strncpy(buff,(char * ) & noOfNodes,sizeof(int));
// strncpy(buff+4,(char *)head,sizeof(struct node *));
memcpy(buff + 4,(char * ) head,sizeof(struct node * ));
printf("noOfNodes: %d\n\n",*(int * ) buff);
printf("1]<%p><%d>\n",head,head -> data);
printf("2]<%p><%d>\n\n",((struct node * ) buff + 4),((struct node * )(buff + 4)) -> data);
printf("address of next node \n");
printf("3]<%p>\n",head -> next);
printf("4]<%p>\n",((struct node * )(buff + 4)) -> next);
return 0;
}
输出:
noOfNodes: 2
1]<0x56450bd632a0><10>
2]<0x56450bd63320><10>
address of next node
3]<0x56450bd632c0>
4]<(nil)>
为什么地址不同?
1]以... 2a0结尾
2]以... 320结尾
如果地址不同,那么它如何正确指向变量data(...-> data)?
为什么(buff + 4)-> next为NULL?它应该与head-> next(即)相同。
struct node *n1 = head;
无论结构节点多大,只要存储8个字节(因为我们正在存储结构节点的地址),我们执行此操作
我想使用memcpy()
(仅使用8个字节)来执行此操作,而在(buff + 4)中仅存储struct node head
的地址,而不是全部struct node
的地址。
这该怎么做 ?那就是为什么我使用(struct node *
)。
解决方法
[tl; dr] Â要将整个*head
复制到buff+4
,memcpy
行需要进行如下更改。
memcpy(buff+4,(char *)head,sizeof(struct node)); // instead of sizeof(struct node *)
使用OP的代码,假设可能出现32b整数和64b指针的情况:
-
填充
-
struct node
以满足指针对齐要求struct node { int data; int hidden_padding_field; // <--- inserted by the compiler struct node *next; };
-
以下代码将
head
的8个字节复制到buff+4
,这意味着head->data
和hidden_padding_field
被复制,而head->next
不会被复制。 >
memcpy(buff+4,sizeof(struct node *));
因此,data
值被正确复制,但是next
指针保持统一。碰巧为NULL完全是偶然的,这只是未定义行为的一种可能表现。
为什么地址不同?
因为buff
数组是与malloc
为head
所存储的数组不同的存储块,所以buff+4
是内存中的不同位置。 / p>
如果地址不同,那么它如何正确指向变量data(...-> data)?
因为您memcpy
在该位置的buff
中放入了一些内存,然后将其从head
指向的内存中复制出来。因此,尽管它是不同的内存块,但写入的数据相同。
为什么(buff + 4)-> next为NULL?
因为您没有复制足够的内存,所以next
成员应保留的部分仍然是复制前buff
的那部分。发生这种情况是因为您告诉memcpy
复制struct node *
占用的内存;但是您不想复制作为指针的内存块,而是想复制作为节点本身的内存块。因此它应该说sizeof(struct node)
而不是sizeof(struct node *)
。
struct node
结构以int data
开头,int
可能的大小与任何 ordinary 指针相同(至少,我想不出更大的任何情况。因此,当我们查看从位置buff + 4
开始的内存时,似乎我们在该位置复制了足够的数据以将正确的值放入->data
中,但对于{{1} }。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。