当前位置: 首页 > 知识库问答 >
问题:

堆中的分配结果是否与堆栈中的分配结果相互依赖?

阮喜
2023-03-14

让我们考虑一下这个代码:

static const size_t DATA_SIZE = 100000;

void log_msg(const char* msg)
{
  char msg_buffer[DATA_SIZE];
  // Do something...
}

int main()
{
  // Do something heap-memory consuming...

  unsigned char buffer = new unsigned char[DATA_SIZE];
  if(!buffer)
  {
    log_msg("Insufficient memory!");
    return 1;
  }

  // Go ahead...

  delete[] buffer;

  return 0;
}

现在,让我们想象一下,在堆中为缓冲区分配内存时,没有可用空间AND,同时,堆栈中有足够的可用空间。

我的问题很简单:如果堆栈中缓冲区的分配是错误的,那么堆栈中msg_buffer的分配是否总是错误的?

据我所知,堆栈是为每个线程分配的,堆是为进程分配的。那么,是否可以保证堆栈中内存分配的结果不会与堆中内存分配的结果相关联?当然,我不认为堆栈溢出本身。换句话说,为堆栈保留的内存实际上是完全为其保留的吗?或者在某些情况下,由于某种原因,在程序执行期间,这个保留可以缩小?

如果没有与平台无关的断言,那么我可以知道是否有针对Linux for x86体系结构的断言。

共有1个答案

徐俊楚
2023-03-14

这是明确依赖于实现的。顺便说一句,堆栈和堆的概念在标准中并不存在,即使它们在现实世界的实现中很常见。

我还记得老式的MS/DOS系统,其中分配类型可能取决于内存模型。一些编译器在小型和中型模型中同时使用一个单一的段(SS)用于堆栈和堆,堆栈从一端生长,堆从另一端生长,但是在小型和大型模型中使用程序上方的内存分配(与堆栈无关)。

在前一种情况下,如果堆栈分配不可能,堆分配也不可能,但在后一种情况下,堆和堆栈分配可以独立地成功或失败。

在使用Linux等虚拟内存的现代操作系统中,通常会有一个固定大小的堆栈,并要求操作系统为堆提供新的空闲块。在这种情况下,堆栈和堆分配可以独立成功或失败

 类似资料:
  • JVM规范(JSE 8版)提到: 第12页:2.5.2 JVM堆栈:“因为JVM堆栈除了用于推送和弹出帧之外,从来没有被直接操作过,所以帧可以被堆分配。” 第15页:2.6:帧:“帧是从创建帧的线程的JVM堆栈中分配的。”在第16页:“请注意,由线程创建的框架是该线程的本地框架,不能被任何其他线程引用。” 这听起来让我很困惑。既然一个帧是创建该帧的线程本地的,为什么要在堆中分配该帧,因为堆在所有J

  • 串的堆分配存储 ,其具体实现方式是采用动态数组存储字符串。 通常,编程语言会将程序占有的内存空间分成多个不同的区域,程序包含的数据会被分门别类并存储到对应的区域。拿 C 语言来说,程序会将内存分为 4 个区域,分别为堆区、 栈区、数据区和代码区,其中的 堆区是本节所关注的。 与其他区域不同,堆区的内存空间需要程序员手动使用 malloc 函数申请,并且在不用后要手动通过 free 函数将其释放。

  • 问题内容: 是局部变量,将其存储在堆或堆栈中的何处? 问题答案: 在堆上。每当您用来创建对象时,它都会在堆上分配。

  • 问题内容: 我是Go的新手,在C风格的基于堆栈的编程(其中自动变量位于堆栈上,分配的内存位于堆中)与Python风格的基于堆栈的编程(其中唯一存在于堆栈中的东西是对堆上对象的引用/指针。 据我所知,以下两个函数给出的输出相同: 即分配一个新的结构并返回它。 如果用C编写,第一个将对象放到堆上,第二个将对象放到堆栈上。第一个将返回指向堆的指针,第二个将返回指向堆栈的指针,该指针将在函数返回时消失,这

  • 我试图了解分配给堆栈和堆的内存量。假设sizeof(char)=1字节,sizeof(void*)=4字节。给定以下代码: 我们被告知分配给堆的内存量是5个字节,我明白这确实是malloc(strlen(str2)=5)中的量。但是,我不明白的是分配给堆栈的内存量是如何达到18个字节的?我想如果他们给我们一个指针大小是4个字节的信息,那么我们有4个字节的指针str1和另外6个字节的数组str2(包

  • 问题内容: 最近,我一直在阅读有关Java中的内存分配方案的大量文章,并且由于我从各种来源中进行了阅读,所以存在很多疑问。我已经收集了我的概念,并要求仔细阅读所有要点并对其进行评论。我知道内存分配是特定于JVM的,因此我必须事先说一下,我的问题是特定于Sun的。 类(由类加载器加载)放在堆上的特殊区域中:永久生成 与类有关的所有信息,例如类的名称,与该类关联的对象数组,JVM使用的内部对象(例如j