让我们考虑以下因子:
#include <iostream.h>
int factorial(int);
void main(void) {
int number;
cout << "Please enter a positive integer: ";
cin >> number;
if (number < 0)
cout << "That is not a positive integer.\n";
else
cout << number << " factorial is: " << factorial(number) << endl;
}
int factorial(int number) {
int temp;
if(number <= 1) return 1;
temp = number * factorial(number - 1);
return temp;
}
如何计算使用函数 factorial()的内存?更准确地说,我想知道函数使用了多少内存?
修改
这只是一个示例程序,我正在处理的程序有很多不同,并且有很多功能,我实际上想要计算每个函数的内存使用情况。
答案 0 :(得分:4)
由于该函数仅使用堆栈内存,因此您可以在temp
之前将return 1
的地址存储在全局变量中,并将其与number
的地址进行比较:
#include <iostream.h>
int factorial(int);
void* tos;
void main(void) {
int number;
cout << "Please enter a positive integer: ";
cin >> number;
if (number < 0)
cout << "That is not a positive integer.\n";
else
cout << number << " factorial is: " << factorial(number) << endl;
cout << "factorial used " << ((char*)&number - (char*)tos) << " bytes of stack.\n";
}
int factorial(int number) {
int temp;
if(number <= 1) {
tos = &temp;
return 1;
}
temp = number * factorial(number - 1);
return temp;
}
答案 1 :(得分:3)
对于我的第二个答案(由我的第一个答案的评论提示),您可以使用一个函数来计算已触摸的堆栈数量。这是一个希望不会对给定架构上的堆栈性质做出太多假设的假设。它假设下降堆栈,这对大多数人来说是相当安全的选择:
#define LU_RAND_SEED 123456789LU
#define LU_RAND(S) ((S) * 69069 + 362437 & 0XFFFFFFFFLU)
int depth(int maxdepth)
{
unsigned long r = LU_RAND_SEED;
int d = 0;
unsigned long *stk = (unsigned long *)alloca(maxdepth);
for (int i = maxdepth/sizeof(unsigned long); i--; )
{
r = LU_RAND(r);
if (stk[i] != r)
{
stk[i] = r;
d = i;
}
}
return maxdepth - d*sizeof(unsigned long);
}
在您要测试的功能之前调用一次,之后调用一次。第二个调用将返回已触摸的堆栈字节数(减去一些您必须通过实验确定的常量值)。您必须确保只有您正在测试的代码在两次调用depth()
之间运行:
depth(512<<10);
int f = factorial(number);
int d = depth(512<<10);
cout << ... f ...
您还必须注意边缘情况。例如,如果number
为0或1,则深度测试失败的原因我尚未弄清楚。善良知道如果编译器开始重用堆栈槽会发生什么。简而言之: caveat emptor 。
注意:
srand()
/ rand()
或他们的线程安全对手可能会正常工作,但我想避免调用alloca()
以外的任何函数。unsigned long r = (unsigned long)&r;
避免了常量种子的稍微随机性,并且它起作用,因为如果对depth()
的两次调用是在不同的堆栈深度进行的,那么这种技术无论如何都会失败。我只是不知道这样生成的种子会有多安全。答案 2 :(得分:2)
使用分析工具 http://code.google.com/p/google-perftools/
或valgrind
答案 3 :(得分:0)
如果您不知道“阶乘”将有多少递归,则无法确定它将消耗多少内存。在32位机器上,此函数的1次递归应消耗8个字节(返回地址为4个字节,参数为4个字节)
答案 4 :(得分:0)
查看编译器生成的映射文件。这将显示所有尺寸。
答案 5 :(得分:0)
计算最大通话深度。 (应在任何算法分析课程中涵盖)
查找每次调用的堆栈使用情况(查看函数的汇编代码,不要忘记查阅CPU架构手册以了解call
指令在堆栈上放置了多少数据。
查找每次调用的动态内存使用情况,查找malloc
和realloc
,C ++运算符new
等函数以及std::vector
等容器类。
乘法。