不同类别的内存

时间:2013-12-12 11:39:13

标签: c++ memory stack

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; 
}

我们目前正在学习不同类别的记忆,我知道这些 -Code Memory - 静态数据 - 运行时间堆栈 - 免费商店(堆)

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

任何人都可以伸出援手吗?

3 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:1)

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()函数的代码将位于exectuable的数据部分。你可以得到一个指向内存地址的指针,并通过该地址调用该函数,但除此之外,你无法用它做任何事情。

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上),但除非你做的事情非常专业,否则它们并不重要:-)

答案 2 :(得分:0)

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

如果你深入研究Windows中的exe加载程序(或实际上在任何类型的操作系统中)它真正做的是存储你的部分的信息(你的部分exe),并在运行时正确地放置它进入内存并应用访问权限。所以通常是代码部分,其中“程序”与数据部分是相同的内存(RAM)。区别在于访问权限不同,代码段通常只读取+执行数据只是读取+写入(并且没有执行)。

堆栈仍然是一个内存,它在某种意义上是特殊的,它再次由操作系统控制,堆栈大小是堆栈大小的字节大小,但这里的目的是保持之间的直接值函数调用(根据stdcall)和局部变量(取决于编译器如何完成它)所以因为它是一个你可以使用它的内存,但就像你一样,让我们​​说在堆栈上分配一个10000字节的字符串。在程序集中你可以直接访问,因为有一个堆栈指针EBP(如果我没记错:P)或者在C / C ++中你可以使用alloca。

新的和删除操作符是为C ++语言构建的,但据我所知它们使用相同的系统分配器,实际上你可以覆盖它们并使用malloc / free,它应该工作,这意味着再次,这是相同的记忆。

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

除此之外还有一些特殊的方法,但是那些会改变内存处理的方式,在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

是的,这将在堆上,但它的分配方式取决于实现,每当你覆盖new运算符时,如果你这样做,你可以强制它在虚拟内存中,所以实际上它可以在磁盘或RAM,但这是愚蠢的事情,是的,它将在堆上。

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

这里发生了多件事,因为编译器知道initialiseArray的第一个参数必须是指向int的指针,它会传递一个指向myArray的指针,所以指针和值30都将进入堆栈,然后是函数叫做。 在内存中的函数(代码部分)中,它运行并从堆栈中获取参数(int * arrayParam,int sizeParam),它将知道您要写入arrayParam,那就是指针,因此它将写入进入位置arrayParam指向。使用arrayParam [i]&lt;指定它的确切位置我会将内存指针偏移到正确的值,C ++通过调整指针为你做了一些魔术,因为代码中的调整应该是以字节为单位,它会将内存指针移动4,因为(通常)int == 4字节。 / p>

为了更好地了解它在何处以及如何工作,请使用调试器或反汇编程序(如OllyDbg)并亲自查看,如果您想了解更多有关堆栈的使用情况的信息,请查看stdcall调用约定