标签: stack-memory

为什么Java不允许对象在栈上?

我正在学习一些具有 C++ 背景的 Java 课程和对象课程。我想知道为什么我们不能选择在堆栈内存上声明的对象?为什么除了原始类型之外的所有内容都必须放在堆上?

这是澄清我所问内容的一些内容。

本质上,如果我们有:

Scanner input = new Scanner(System.in);

那么为什么我们不能首先将它放在堆栈上呢?

java heap-memory stack-memory

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

汇编 x86-64 从堆栈中获取函数参数

最近,我一直在从《从头开始编程》一书中学习 x86 汇编,但我有一台 x86-64 计算机,所以事情在某一时刻开始出错(在本书的早期)。我谈到了处理函数的部分,特别是电源示例。在此示例中,他将参数压入堆栈,然后将它们复制到函数后面的寄存器中。他的代码如下:

pushl $3                        # second argument
pushl $2                        # first argument
call power                      # call function
...
power:
  pushl %ebp                    # save old base pointer
  movl %esp, %ebp               # make stack pointer the base pointer
  subl $4, %esp                 # get room for our local storage

  movl 8(%ebp), %ebx            # put first argument in %eax
  movl 12(%ebp), %ecx           # put second argument in %ecx
Run Code Online (Sandbox Code Playgroud)

当然,这是32位的,而我运行的是64位,所以我尝试更新寄存器和指令后缀,最终得到这样的结果(这次不需要注释):

pushq $3
pushq $2
call power
...
power: …
Run Code Online (Sandbox Code Playgroud)

linux assembly x86-64 function stack-memory

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

这种在 C++ 中创建局部变量的方法是合法的

我是 C++ 新手,尝试了解如何在 C++ 中创建和使用类。为此,我有以下代码:

class MyClass
{ 
    public:
    MyClass()
    {
        _num = 0;
        _name = "";
    }

    MyClass(MyClass* pMyClass)
    {
        _num = pMyClass->_num;
        _name = pMyClass->_name;
    }

    void PrintValues() { std::cout << _name << ":" << _num << std::endl; }
    void SetValues(int number, std::string name)
    {
        _num = number;
        _name = name;
    }

    private:
    int _num;
    std::string _name;
};


int main()
{
    std::vector<MyClass*> myClassArray;
    MyClass myLocalObject = new MyClass();

    for (int i = 0; i < 3; i++)
    { …
Run Code Online (Sandbox Code Playgroud)

c++ constructor initialization heap-memory stack-memory

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

堆栈是在进程中预先分配的吗?

好吧,我的问题如下,我在某处看到一个linux进程在堆栈上分配8 MiB供使用,例如,如果我有一个C程序,我只在堆栈上分配两个变量,这是正确的说法我分配了或者更好地说我只是重复使用了该空间?由于进程在堆栈上分配 8 MiB,因此它不取决于我将在程序中使用的大小,只要它不超过我的堆栈,即无论哪个术语合适,我都会在堆栈或者我将重用Linux进程已经分配的数据?

#include <stdio.h>

void f() {
   int x = 5;
   printf("Value = %d End = %p\n", x, &x);
}

void g() {
   int y = 10;
   printf("Value = %d End = %p\n", y, &y);
}

int main(){

  f();
  g();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

看到地址将是相同的,因为我重复使用了已经分配的大小,而 malloc 不会发生同样的情况,总结术语“在堆栈中分配正确的数据”不是很正确?

c linux assembly x86-64 stack-memory

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

使用未优化的 C (GCC) 固定大小缓冲区的 x86-32 和 x64 汇编堆栈分配的差异

进行一些基本的反汇编,并注意到由于某种原因,缓冲区被给予了额外的缓冲区空间,尽管我在教程中看到的内容使用相同的代码,但仅给出了正确的(500)个字符长度。为什么是这样?

我的代码:

#include <stdio.h>
#include <string.h>

int main (int argc, char** argv){
    char buffer[500];
    strcpy(buffer, argv[1]);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

用GCC编译,反汇编代码为:

   0x0000000000001139 <+0>:     push   %rbp
   0x000000000000113a <+1>:     mov    %rsp,%rbp
   0x000000000000113d <+4>:     sub    $0x210,%rsp
   0x0000000000001144 <+11>:    mov    %edi,-0x204(%rbp)
   0x000000000000114a <+17>:    mov    %rsi,-0x210(%rbp)
   0x0000000000001151 <+24>:    mov    -0x210(%rbp),%rax
   0x0000000000001158 <+31>:    add    $0x8,%rax
   0x000000000000115c <+35>:    mov    (%rax),%rdx
   0x000000000000115f <+38>:    lea    -0x200(%rbp),%rax
   0x0000000000001166 <+45>:    mov    %rdx,%rsi
   0x0000000000001169 <+48>:    mov    %rax,%rdi
   0x000000000000116c <+51>:    call   0x1030 <strcpy@plt>
   0x0000000000001171 <+56>:    mov    $0x0,%eax
   0x0000000000001176 <+61>:    leave  
   0x0000000000001177 <+62>:    ret  
Run Code Online (Sandbox Code Playgroud)

然而,这个视频 …

c assembly x86-64 buffer-overflow stack-memory

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

dart 中的值存储在内存中的哪里?

我知道在 Dart 中所有数据类型都是对象,包括数字和布尔值,在其他语言中数字和布尔值存储在堆栈中,复杂数据(如对象或列表)存储在堆中,在 Dart 中它如何存储它?内存中的值?我只想知道这一点。

memory memory-management heap-memory stack-memory dart

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

C函数局部变量在函数执行后没有被释放

在下面的 C 程序中,对函数的调用创建了一个相当大的局部变量buf,然后函数返回并且程序处于无限循环中。buf正如人们所预料的那样,在调用该函数时,系统的 RAM 使用量会增加等于 的大小;但是,函数返回后(显示“完成”),RAM 使用量不会下降,而是保持不变。

为什么函数返回后这个堆栈分配的缓冲区没有立即释放?如何制定这种行为的一般行为,并描述在哪些情况下它可能会或可能不会立即释放?

#include <stdlib.h>
#include <stdio.h>

void f()
{
    int buf[1000 * 1000 * 200];
}

int main()
{
    f();
    printf("Done\n");
    for (;;);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

下面是运行程序时的 RAM 使用时间线。 RAM 使用时间线

PS 这是在 Linux Ubuntu 上运行的。

PS 我编译时没有进行编译器优化

PSf以“闪烁”方式调用(重复[开 - 延迟 - 关 - 延迟])而不是一次调用会导致类似的 RAM 使用时间线。

c stack-memory

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

如何判断对象是在栈内存还是堆内存

我最近收到了一份数据结构课程的大学作业,要求我用 C++ 创建一个双向链表

在处理双向链表时,我需要实现各种功能,但特别引起我注意的一种方法是“clear()”。该方法负责清除双向链表内的所有元素:

void clear(Node* head_ptr)
{
    Node* previous_ptr = nullptr;

    while(head_ptr != nullptr)
    {
        previous_ptr = head_ptr; // Store previous node.

        head_ptr = head_ptr->next;

        delete previous_ptr;
    }
};
Run Code Online (Sandbox Code Playgroud)

该方法非常简单;它只是迭代所有元素并为每个元素释放内存Node。然后,我在析构函数中调用此方法,如下所示:

~List()
{
    clear_list(m_head_ptr);
};
Run Code Online (Sandbox Code Playgroud)

然后我开始思考。如果我的节点元素位于堆上,这种释放内存的方法就很好,如下所示:

int main()
{
    List list;

    Node* node_1 = new Node(3, nullptr);    // The tail node.
    Node* node_2 = new Node(1, node_1);
    Node* node_3 = new Node(5, node_2);
    Node* node_4 = new Node(7, …
Run Code Online (Sandbox Code Playgroud)

c++ list heap-memory stack-memory

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

const参考函数参数的地址何时是唯一的?

在下面的示例代码中,我想知道两次调用log_cref_address何时可靠地打印相同的地址.

#include <iostream>
#include <thread>
#include <functional>

using namespace std;

void log_cref_address(const int& t) {
    cout << addressof(t) << ' ';
}

template <int i>
void foo() {
    log_cref_address(i); // different if foo called from different threads
    thread([] { log_cref_address(i); }).join(); // same if already in thread
    thread(log_cref_address, i).join(); // same if already in thread
    cout << endl;
}

int main() {
    // first three calls print identical addresses
    cout << "foo<0>: "; foo<0>(); 
    cout << "foo<0>: "; …
Run Code Online (Sandbox Code Playgroud)

c++ cross-platform addressof stack-memory pass-by-const-reference

0
推荐指数
1
解决办法
47
查看次数

重新为堆栈和堆指针分配内存

我开发了如下的阻塞队列类

class Blocking_queue
{
public:
    Blocking_queue();

    int put(void* elem, size_t elem_size);
    int take(void* event);

    unsigned int get_size();

private:

    typedef struct element
    {
        void* elem;
        size_t elem_size;
        struct element* next;
    }element_t;

    std::mutex m_lock;
    std::condition_variable m_condition;
    unsigned int m_size;
    element_t* m_head;
    element_t* m_tail;

};
Run Code Online (Sandbox Code Playgroud)

我希望该类尽可能通用,因此我正在使用一个void指针,该指针在元素添加到队列时分配,在从队列中删除时释放。

int Blocking_queue::take(void* event)
{
    element_t* new_head = NULL;
    int ret = 0;

    // Queue empty
    if(nullptr == m_head)
    {
        // Wait for an element to be added to the queue
        std::unique_lock<std::mutex> unique_lock(m_lock);
        m_condition.wait(unique_lock);
    }

    if(nullptr == realloc(event, …
Run Code Online (Sandbox Code Playgroud)

c++ heap-memory stack-memory memory-reallocation

0
推荐指数
1
解决办法
69
查看次数