不同类别的内存

Different categories of memory

本文关键字:内存 同类      更新时间:2023-10-16
static const int MAX_SIZE = 256; //I assume this is static Data
bool initialiseArray(int* arrayParam, int sizeParam) //where does this lie?
{ 
 if(size > MAX_SIZE) 
 { 
 return false; 
 } 
 for(int i=0; i<sizeParam; i++) 
 { 
 arrayParam[i] = 9; 
 } 
 return true; 
} 
void main() 
{ 
 int* myArray = new int[30]; //I assume this is allocated on heap memory
 bool res = initialiseArray(myArray, 30); //Where does this lie?
 delete myArray; 
}

我们目前正在学习不同类别的记忆,我知道有-代码存储器-静态数据-运行时堆栈-免费商店(堆(

我已经评论了我不确定的地方,只是想知道是否有人可以帮助我。我对运行时堆栈的定义描述这是用于函数的,但我的代码内存定义它包含方法/函数的所有指令,所以我有点困惑。

谁能伸出援手?

static const int MAX_SIZE = 256; //I assume this is static Data

确实是的。事实上,因为它是const的,这个值可能根本不会保留在你的最终可执行文件中,因为编译器可以在它看到MAX_SIZE的任何地方替换"256"。

bool initialiseArray(int* arrayParam, int sizeParam) //where does this lie?

initialiseArray()函数的代码将位于可执行数据部分。你可以获取一个指向内存地址的指针,并通过该地址调用函数,但除此之外,你没有太多可以做的。

arrayParamsizeParam 参数将在堆栈上按值传递给函数。同样,bool返回值将被放置在调用函数的堆栈区域中。

int* myArray = new int[30]; //I assume this is allocated on heap memory

正确。

 bool res = initialiseArray(myArray, 30); //Where does this lie?

实际上,myArray指针和文字30被复制到 initialiseArray() 的堆栈区域中,然后对它们进行操作,然后将生成的bool复制到调用函数的堆栈区域中。

参数传递的实际细节要多得多,并且取决于调用约定(其中有几个,特别是在Windows上(,但除非你正在做一些真正专业的事情,否则它们并不重要:-(

堆栈用于自动变量 - 即在函数中声明的变量,或作为函数参数声明的变量。当程序离开声明它们的代码块时,这些变量会自动销毁。

您是对的,MAX_SIZE具有静态生存期 - 它在程序结束时会自动销毁。您也正确,分配了new[]的数组位于堆上(具有动态生存期( - 它不会自动销毁,因此需要删除。顺便说一句,您需要delete [] myArray;来匹配new []的使用.

指向它的指针(myArray(是一个自动变量,在堆栈上,res和函数参数也是如此。

只有一种类型的内存...这是一个记忆:D不同的是它在哪里以及如何访问它。

如果您深入了解Windows(或实际上在任何类型的操作系统中(中的exe加载程序,它真正做的是存储您的部分(exe的一部分(的信息,并在运行时将其正确布局到内存中并应用访问权限。所以一般来说,你的"程序"的代码部分与你的数据部分是相同的内存(你的RAM(。区别在于访问权限不同,代码段通常只有读+执行数据只是读+写(而没有执行(。

堆栈

仍然是一个内存,它的特殊之处在于它再次由操作系统控制,堆栈大小是堆栈大小的字节大小,但这里的目的是在函数调用(根据 stdcall(和局部变量(取决于编译器如何完全做到(之间保存即时值就是假设在堆栈上分配一个 10000 字节的字符串。在汇编中,您可以直接访问,因为有一个堆栈指针 EBP(如果我没记错的话:P(,或者在 C/C++ 中您可以使用 alloca。

new 和 delete 运算符是 C++ 语言的内置运算符,但据我所知,它们使用与您相同的系统分配器,实际上您可以覆盖它们并使用 malloc/free,它应该可以工作,这意味着这再次是相同的内存。

使用

new/delete 和特定于操作系统的函数之间的区别在于,您可以让语言处理分配,但最终您将获得一个指针,就像使用任何其他函数一样。

除此之外,还有一些特殊方法,但这些方法会改变内存的处理方式,例如在Windows中,这是虚拟内存,例如VirutalAlloc,VirutalFree将允许您指定要使用的内存将执行的操作,从而允许操作系统更好地优化,就像您告诉它我想要2Gb内存,但它不必在RAM中, 所以它可能会将其保存在磁盘上,但您仍然使用内存指针访问它。

关于您的问题:

static const int MAX_SIZE = 256; //I assume this is static Data

它通常取决于编译器,但大多数情况下他们会将其视为 const(静态是其他东西(,这意味着它将在 exe 的 const 部分,这反过来意味着这个内存块将是只读的。

 int* myArray = new int[30]; //I assume this is allocated on heap memory
是的,这将在堆上,

但是如何分配它取决于实现,并且每当您覆盖新运算符时,如果您这样做,例如可以强制它位于虚拟内存中,因此实际上它可能在磁盘上或RAM中,但这样做是愚蠢的事情,是的,它将在堆上。

bool res = initialiseArray(myArray, 30); //Where does this lie?

这里发生了多件事,因为编译器知道 initialiseArray 的第一个参数必须是指向 int 的指针,它将传递指向 myArray 的指针,因此指针和值 30 都将进入堆栈,然后调用函数。在内存中的函数(代码部分(中,它运行并从堆栈中获取参数(int* arrayParam,int sizeParam(,它将知道您要写入arrayParam,即指针,因此它将写入arrayParam指向的位置。到你用arrayParam[i]指定它的确切位置

为了更好地了解它在哪里做什么以及它是如何工作的,请使用调试器或反汇编器(如 OllyDbg (并亲自查看它,如果您想了解有关堆栈如何使用的更多信息,请查看 stdcall 调用约定。