标签: stack-memory

C/C++中的并发编程,堆栈和堆

好吧,如果这感觉像是重复旧问题,我很抱歉,我已经通过tanenbaum对Stack Overflow,现代操作系统手册进行了几个问题,并且仍然要清除我对此的怀疑.

首先,我将非常感谢我应该更详细地阅读的任何书籍/资源,以便更好地理解这种结构.我不明白这些是OS书籍或编程语言或架构书籍中通常解释的概念.

在我提出问题之前,我会根据有关堆栈/堆的读数列出我的发现

  • 仅包含所有实例变量,动态分配(new/malloc)和全局变量
  • 不再使用数据结构堆,使用更复杂的结构
  • 通过内存位置访问,负责分配内存的单个进程
  • 碎片整理和内存分配由操作系统完成(如果是或否,请回答我关于谁管理堆,操作系统或运行时环境的问题)
  • 在进程中可以访问其引用的所有线程之间共享

  • 仅包含所有局部变量.(在功能调用时推送)
  • 使用实际的堆栈数据结构进行操作
  • 由于连续的性质,访问速度更快

现在,关于我的一些问题.

  1. 全局变量,它们在哪里被分配?(我的信念是它们被分配在堆上,如果是这样,它们何时被分配,在运行时或编译时,还有一个问题,是否可以清除此内存(如使用删除)?)
  2. 堆的结构是什么?堆是如何组织的(由os或运行时环境管理(由C/C++编译器设置)).
  3. 堆栈是否包含ONLY方法及其局部变量?
  4. 每个应用程序(进程)都有一个单独的堆,但如果超过堆分配,那么它是否意味着操作系统无法分配更多内存?(我假设内存不足导致操作系统重新分配以避免碎片)
  5. 可以从进程中的所有线程访问堆(我相信这是真的).如果是,则所有线程都可以访问实例变量,动态分配的变量,全局变量(如果它们有引用它)
  6. 不同的进程,无法访问彼此堆(即使它们传递了地址)
  7. 堆栈溢出崩溃
    • 只有当前的线程
    • 目前的过程
    • 所有过程
  8. 在C/C++中,内存是否在堆栈运行时为函数内的块变量分配(例如,如果代码的子块(例如For循环)创建了一个新的变量,则在运行时分配堆栈(或堆)或它是否已预先分配?)何时删除它们(块级范围,如何维护).我对此的看法是,堆栈的所有添加都是在块的开始之前在运行时进行的,每当到达该块的结尾时,所有添加到该点的元素都被推送.
  9. CPU对堆栈寄存器的支持仅限于堆栈指针,可以通过正常访问内存来递增(弹出)和递减(推送).(这是真的?)
  10. 最后,是主存储器上存在的OS /运行时环境生成的堆栈和堆结构(作为抽象?)

我知道这很多,而且我似乎总是非常困惑,如果你能指出我正确的方向让这些事情得到澄清,我将不胜感激!

c++ parallel-processing memory-management heap-memory stack-memory

7
推荐指数
1
解决办法
1863
查看次数

是否可以将std :: array移动到std :: vector中?

这是关于堆栈内存和堆内存的交互以及通过std::arraystd::vector类从堆栈到堆的特定情况的问题.

原则std::array<T>上可以看作是指向第一个元素的指针,加上一些关于数组大小的编译时间信息.是否有可能让std::vector<T>构造函数考虑到这一事实并尝试通过复制指针将内容移动arrayvectorjust中.

一个用例是,一个具有返回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::vectorstd::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)

move heap-memory stack-memory c++11 stdarray

7
推荐指数
2
解决办法
1419
查看次数

如何检测内存是否来自堆栈?(不是堆或静态变量)

虽然没有官方支持的方法来做到这一点.有没有办法(在现代系统上)检测指针是否来自堆栈(例如调用者的堆栈).

即使这不能作为实际代码逻辑的一部分工作,它也可以帮助避免可以检测到它的配置中的错误,例如:

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)

c stack-memory

7
推荐指数
1
解决办法
123
查看次数

Swift 结构总是存储在堆栈中吗?

在一次面试中,我被要求概述Swift 中结构体之间的区别。在我的观点中,我提出了这样的论点:结构存储在堆栈中(它们的空间在编译时保留),而存储在堆中(空间在运行时分配)。

然后面试官说他真的会测试我对 Swift 的了解有多深,然后问我结构体是否总是存储在堆栈中。经过一番来回,他做出了这样的声明:

如果结构体长度超过 3 个字,则将其分配在堆中

我在网上做了一些研究,但似乎在任何地方都找不到这个。谁能证实或否认这一说法的有效性?另外,请随意添加任何相关/有效信息。

memory struct heap-memory stack-memory swift

7
推荐指数
0
解决办法
3093
查看次数

将在何处进行C中字符串的内存分配

对于下面给出的C语句,我想知道memmory分配将在何处进行.

char* ptr="Hello";//ptr is a automatic variable
Run Code Online (Sandbox Code Playgroud)

那么指针变量ptr将在堆栈上分配,但是这个字符串"Hello"将被分配到哪里.它是在堆栈上还是在堆上?那么初始化语句的内存分配如char ptr [] ="Hello";

c memory-management heap-memory stack-memory

6
推荐指数
1
解决办法
384
查看次数

我可以从堆栈中 POP 一个值,但在 NASM 程序集中无处放置吗?

NASM 程序集,Ubuntu,32 位程序。

通常,当从堆栈中弹出一个值时,我会做

POP somewhere
Run Code Online (Sandbox Code Playgroud)

放入寄存器或变量。但有时,我只是不想把它放在任何地方——我只想摆脱堆栈中的下一个元素。正在做

POP
Run Code Online (Sandbox Code Playgroud)

就像那样是行不通的。

我的解决方法是制作一个我根本不使用的 4 字节变量并将其转储POP到其中。有没有更好的方法来实现这一目标?

x86 stack nasm stack-memory stack-pointer

6
推荐指数
2
解决办法
3271
查看次数

数组作为模板参数:堆栈还是堆?

与堆相比,我对堆栈的了解非常简陋,但是当涉及到数组时,从我所知道的内容就是在堆栈上创建的

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)

c++ arrays templates heap-memory stack-memory

6
推荐指数
1
解决办法
1188
查看次数

我的结构何时太大?

我们鼓励在 Swift 中使用structover class

这是因为

  1. 编译器可以做很多优化
  2. 实例是在堆栈上创建的,这比malloc/free调用性能要高得多

变量的缺点struct是每次从函数返回或分配给函数时都会复制它们。显然,这也可能成为瓶颈。

例如,想象一个 4x4 矩阵。每次分配/返回时都必须复制 16 个浮点值,在 64 位系统上这将是 1'024 位。

避免这种情况的一种方法是inout在将变量传递给函数时使用,这基本上是 Swift 创建指针的方法。但我们也不鼓励使用inout.

所以我的问题是:
我应该如何在 Swift 中处理大型、不可变的数据结构?
我是否需要担心创建一个struct包含许多成员的大型项目?
如果是的话,我什么时候越界?

struct class heap-memory stack-memory swift

6
推荐指数
1
解决办法
2206
查看次数

Swift 中的全局函数和变量存储在哪里?

根据我的理解,堆栈用于存储值类型(如枚举和结构)和引用到堆中的对象(如类实例)的变量。此外,Stack 还以 LIFO 方式保存带有各自参数等的函数调用。

在 C 中,有4 个通用内存段(堆、堆栈、数据、代码),其中数据段通常存储全局变量和静态变量,这意味着它们存储和管理的内存完全独立的方面,但我这样做相信 Java 以不同的方式处理它(在 JVM 方面有一些魔法)。

如果我在 Swift 中声明了一个全局变量,变量将如何/在哪里存储?例如,与在 XCode 的项目模块中声明全局/静态变量/函数相比,如果我只是玩弄 Playground 文件,这会有所不同吗?

static global heap-memory stack-memory swift

6
推荐指数
0
解决办法
574
查看次数

默认情况下,Rust 闭包是堆栈分配还是堆分配?

我知道 Rust 默认在堆栈上分配,但论文所有权是盗窃说 Rust 闭包通常是动态分配的(我认为这意味着“在堆上”)。

heap-memory stack-memory rust

6
推荐指数
1
解决办法
230
查看次数