好吧,如果这感觉像是重复旧问题,我很抱歉,我已经通过tanenbaum对Stack Overflow,现代操作系统手册进行了几个问题,并且仍然要清除我对此的怀疑.
首先,我将非常感谢我应该更详细地阅读的任何书籍/资源,以便更好地理解这种结构.我不明白这些是OS书籍或编程语言或架构书籍中通常解释的概念.
在我提出问题之前,我会根据有关堆栈/堆的读数列出我的发现
堆
堆
现在,关于我的一些问题.
我知道这很多,而且我似乎总是非常困惑,如果你能指出我正确的方向让这些事情得到澄清,我将不胜感激!
c++ parallel-processing memory-management heap-memory stack-memory
这是关于堆栈内存和堆内存的交互以及通过std::array和std::vector类从堆栈到堆的特定情况的问题.
原则std::array<T>上可以看作是指向第一个元素的指针,加上一些关于数组大小的编译时间信息.是否有可能让std::vector<T>构造函数考虑到这一事实并尝试通过复制指针将内容移动array到vectorjust中.
一个用例是,一个具有返回a的函数 std::array<double, >
std::array<double, 20> fun(){...};
但是后来决定将其分配给a std::vector而不必逐个元素地复制.
std::vector<double> v = fun(); // not working code
现在必须要做
std::array<double, 20> tmp = fun();
std::vector<double> v(tmp.begin(), tmp.end());
Run Code Online (Sandbox Code Playgroud)
这实际上是一些多余的工作,如果可能的话,这些工作是不必要的std::vector<double> v(std::move(tmp)); \\ not working code.
内存布局std::vector和std::array是一样的,所以不是和障碍.
我知道主要的障碍可能是std::array元素在堆中,而std::vector元素在堆中.很明显,即使std::vector从堆栈中写入仍然存储器的移动构造函数也将被无可挽回地破坏.
所以我想这个问题也可以解读为:
有没有办法将内存从堆栈移动到堆(无论这意味着什么),如果可以与移动构造函数结合使用?
或者如果原则上std::vector可以从一个移动构造函数?std::array
MWE:
#include<array>
#include<vector>
std::array<double, 20> fun(){return {};} // don't change this function …Run Code Online (Sandbox Code Playgroud) 虽然没有官方支持的方法来做到这一点.有没有办法(在现代系统上)检测指针是否来自堆栈(例如调用者的堆栈).
即使这不能作为实际代码逻辑的一部分工作,它也可以帮助避免可以检测到它的配置中的错误,例如:
void my_function(void *arg) {
/* Only some configurations can do this (depending on compiler & arch). */
#if THE_MOONS_ALIGN
assert(not_stack_memory(arg));
#endif
/* ... actual logic ... */
}
Run Code Online (Sandbox Code Playgroud) 在一次面试中,我被要求概述Swift 中结构体和类之间的区别。在我的观点中,我提出了这样的论点:结构存储在堆栈中(它们的空间在编译时保留),而类存储在堆中(空间在运行时分配)。
然后面试官说他真的会测试我对 Swift 的了解有多深,然后问我结构体是否总是存储在堆栈中。经过一番来回,他做出了这样的声明:
如果结构体长度超过 3 个字,则将其分配在堆中
我在网上做了一些研究,但似乎在任何地方都找不到这个。谁能证实或否认这一说法的有效性?另外,请随意添加任何相关/有效信息。
对于下面给出的C语句,我想知道memmory分配将在何处进行.
char* ptr="Hello";//ptr is a automatic variable
Run Code Online (Sandbox Code Playgroud)
那么指针变量ptr将在堆栈上分配,但是这个字符串"Hello"将被分配到哪里.它是在堆栈上还是在堆上?那么初始化语句的内存分配如char ptr [] ="Hello";
NASM 程序集,Ubuntu,32 位程序。
通常,当从堆栈中弹出一个值时,我会做
POP somewhere
Run Code Online (Sandbox Code Playgroud)
放入寄存器或变量。但有时,我只是不想把它放在任何地方——我只想摆脱堆栈中的下一个元素。正在做
POP
Run Code Online (Sandbox Code Playgroud)
就像那样是行不通的。
我的解决方法是制作一个我根本不使用的 4 字节变量并将其转储POP到其中。有没有更好的方法来实现这一目标?
与堆相比,我对堆栈的了解非常简陋,但是当涉及到数组时,从我所知道的内容就是在堆栈上创建的
float x[100];
Run Code Online (Sandbox Code Playgroud)
而这样的东西是在堆上创建的
float* x = new float[100];
Run Code Online (Sandbox Code Playgroud)
但是如果我创建一个模板数组类,并以"堆栈"数组类型(如float[100])传递它会发生什么?例:
#include <iostream>
using namespace std;
template <class T>
class Array {
public:
int size;
T* data;
Array(int size_) : size(size_) {
data = new T[size];
}
~Array() {
delete [] data;
}
};
int main() {
int m = 1000000;
const int n = 100;
Array<float[n]>* array = new Array<float[n]>(m);
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++) …Run Code Online (Sandbox Code Playgroud) 我们鼓励在 Swift 中使用structover class。
这是因为
malloc/free调用性能要高得多变量的缺点struct是每次从函数返回或分配给函数时都会复制它们。显然,这也可能成为瓶颈。
例如,想象一个 4x4 矩阵。每次分配/返回时都必须复制 16 个浮点值,在 64 位系统上这将是 1'024 位。
避免这种情况的一种方法是inout在将变量传递给函数时使用,这基本上是 Swift 创建指针的方法。但我们也不鼓励使用inout.
所以我的问题是:
我应该如何在 Swift 中处理大型、不可变的数据结构?
我是否需要担心创建一个struct包含许多成员的大型项目?
如果是的话,我什么时候越界?
根据我的理解,堆栈用于存储值类型(如枚举和结构)和引用到堆中的对象(如类实例)的变量。此外,Stack 还以 LIFO 方式保存带有各自参数等的函数调用。
在 C 中,有4 个通用内存段(堆、堆栈、数据、代码),其中数据段通常存储全局变量和静态变量,这意味着它们存储和管理的内存完全独立的方面,但我这样做相信 Java 以不同的方式处理它(在 JVM 方面有一些魔法)。
如果我在 Swift 中声明了一个全局变量,变量将如何/在哪里存储?例如,与在 XCode 的项目模块中声明全局/静态变量/函数相比,如果我只是玩弄 Playground 文件,这会有所不同吗?
我知道 Rust 默认在堆栈上分配,但论文所有权是盗窃说 Rust 闭包通常是动态分配的(我认为这意味着“在堆上”)。