有关存储过程和功能共享的问题

如何解决有关存储过程和功能共享的问题

1)为什么我们不能在c中使用虚拟地址来代替变量,例如为什么要写int x呢?我们可以创建一个指向栈中第一个地址的指针,例如int * x = 1; ,如果我们喜欢声明第二个变量。 我们使用了下一个地址,例如int * y = 2。 或者我们可以使用堆栈中最后一个地址作为动态数组,而不是使用堆。

2) 函数是否共享相同的堆栈,如果它们共享,为什么我们不能在函数之外访问函数的局部变量。 我认为他们没有,但是我看不到函数上下文的变化,因为他们没有同时朗诵

3) 长类型是否在堆栈中占用两个地址,每个地址均为4个字节?

如果不是,则更改数学运算符

解决方法

  1. 为什么我们不能在c中使用虚拟地址来代替变量,例如为什么要写int x呢?我们可以创建一个指向栈中第一个地址的指针,例如int * x = 1; ,如果我们喜欢声明第二个变量。我们使用了下一个地址,例如int * y = 2。或者我们可以使用堆栈中最后一个地址作为动态数组,而不是使用堆。

好吧,您可以使用虚拟地址来代替变量,例如int* a=(int*)0x8000B,它仅在没有OS的环境中才能工作,例如在Bootloader中,因为如果使用了地址,则加载的程序通常是不同的操作系统。

您可以执行int* x=(int*)1int* x=(int*)5,但是在某些体系结构上可能会崩溃,因为这些体系结构与sizeof(int)的倍数不对齐(通常为2或4个字节)。 此外,如果您在没有操作系统的情况下编写程序,则该地址仅适用于此类地址,因为大多数操作系统会保留前几页。 ==>您无法对他们做任何事情。

我们可以使用堆栈中最后一个地址作为动态数组,而不是使用堆。

对不起,我真的不明白你的意思。堆栈不是动态数组,它只是一个内存地址和一些可用空间(例如“普通” PC上为2MB或嵌入式设备中只有几百个字节)。

  1. 函数共享相同的堆栈,如果它们共享,为什么我们不能在函数之外访问函数的局部变量。我认为他们没有,但是我看不到函数上下文的变化,因为他们没有同时朗诵

是的,它们共享相同的堆栈。 您可以通过一些技巧来访问它们,但是这些都是非常邪恶的。 假设您有一个函数_start。它从一个空堆栈开始(rbp = 0x1000,rsp = 0x1000)。然后,一些局部变量分配在堆栈上。 (rbp = 0x1000,rsp = 0xff0)。之后,它将调用main。 要跳转到的地址存储在堆栈中,并且更新了基本指针。 现在,堆栈指针和堆栈基指针具有以下地址:rbp = 0xfe8,rsp = 0xfe8 由于SysV-ABI要求16字节对齐,因此您必须再次减去8字节。 rbp = 0xfe8,rsp = 0xfe0。 现在,您可以从使用movq 22(%rsp),%rax开始访问一些局部变量。您现在可能拥有本地的一部分或整个本地。 每次对源代码或编译器标志进行细微更改,此技巧都会失败。

  1. long类型是否在堆栈中占用两个地址,每个地址均为4个字节?

否,长型占用栈中sizeof(long)个字节。地址的大小固定。四个(32位系统)或八个(64位系统)。

,

例如写int x;我们可以创建一个指向堆栈中第一个地址的指针

因为C比汇编程序更高级。 C语言不知道也不关心堆栈的存在。与汇编程序相比,高级语言的主要好处之一是消除了手动堆栈管理。因为汇编器中最常见的错误之一就是忘记在堆栈上压入/弹出某些内容-您永远不会遇到C语言中的错误,因为处理堆栈的指令是由编译器生成的。

因此C程序员不希望手动处理堆栈,主要是因为这样做很麻烦。您描述的伪代码与汇编程序的工作方式非常接近,汇编程序通常与堆栈指针有关。 “读取内存位置SP + 3”等。

或者我们可以使用栈中最后一个地址作为动态数组,而不是使用堆

否,因为堆栈的大小有限,并且作为ABI调用约定的一部分,还用于存储寄存器和返回地址。堆是一个较高层的概念,可以存储大块数据并与同一进程内的所有内容共享,甚至与其他进程共享,具体取决于系统。

编程老师将事情简化很多并说有两种形式的内存是一个常见的问题:堆栈和堆。然后,学生迷上了这两个,并开始做出各种疯狂的结论。实际上,主流计算机具有.stack.data.bss.heap.rodata.text和其他各种细分市场(通常是提到的)。变量可以存储在任何这些段中。例如,如果它们被优化为寄存器访问而不是存储在堆栈中,则它们最终会与.text内部的程序代码混合在一起。

函数共享相同的堆栈

如果您的意思是如果不同函数中的局部变量共享同一堆栈,那么是的,它们在正常情况下(假设单线程,单进程)也会这样做。

long类型是否在堆栈中占用两个地址,每个地址均为4个字节?

标准未指定long的大小,该大小可能为4或8个字节。分配它们的位置取决于上下文。

,
  1. 为什么我们不能在c中使用虚拟地址来代替变量,例如为什么要写int x呢?我们可以创建一个指向栈中第一个地址的指针,例如int * x = 1; ,如果我们喜欢声明第二个变量。我们使用了下一个地址,例如int * y = 2。或者我们可以使用堆栈中最后一个地址作为动态数组,而不是使用堆。

在C中,如果要堆栈存储,则可以声明局部变量或使用alloca分配堆栈内存。例如,我们可以这样做:

#include <iostream>

int main()
{
    typedef struct {
        int x;
        int y;
    } myStruct;

    myStruct *p = (myStruct *) alloca ( sizeof myStruct );

    p -> x = 100;
    p -> y = 200;
    p -> x += 100;
}

这为我们提供了xy的存储空间,可以通过p->xp->y进行引用。

但是,使用局部变量要简单得多,并且要求编译器做更少的工作来确定局部变量甚至不需要堆栈存储,它们可以直接存在于CPU寄存器中。

  1. 函数共享相同的堆栈,如果它们共享,为什么我们不能在函数之外访问函数的局部变量。我认为他们没有,但是我看不到函数上下文的变化,因为他们没有同时朗诵

对于每个线程,都有一个动态调用链,该线程中的所有函数都为局部变量共享同一堆栈。更具体地说,函数调用从概念上激活了堆栈中的帧或记录。

确实存在允许非本地引用的语言,即非本地引用但不是全局引用。这样的语言通常支持嵌套在函数内的函数。特别是对于一流的函数(函数指针),这些通常称为闭包。在像Pascal这样的较老的语言中,使用非局部变量可以为穷人提供面向对象的编程能力。要支持其中的任何一种,都需要在幕后,框架指针和反向链接等方面投入大量精力.C编程语言选择不实现嵌套函数,我认为这是出于简化目的。可以使用更通用的堆对象(但需要手动分配和释放)来代替它。

  1. long类型是否在堆栈中占用两个地址,每个地址均为4个字节?

可能是的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地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-