为什么地址不同但仍指向相同的数据?

如何解决为什么地址不同但仍指向相同的数据?

#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+4memcpy行需要进行如下更改。

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->datahidden_padding_field被复制,而head->next不会被复制。

  • >
memcpy(buff+4,sizeof(struct node *));

因此,data值被正确复制,但是next指针保持统一。碰巧为NULL完全是偶然的,这只是未定义行为的一种可能表现。

,

为什么地址不同?

因为buff数组是与mallochead所存储的数组不同的存储块,所以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 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res