我试图计算程序中使用的堆栈内存。
#define ARRAY1_LIMIT 200
#define ARRAY2_LIMIT 100
char* array1[ARRAY1_LIMIT];
char* array2[ARRAY2_LIMIT];
int i = 0;
int j = 0
array1[i] = (char *)malloc(sizeof(char)*5);
array2[j] = (char *)malloc(sizeof(char)*10);
我知道堆内存是5 + 15 = 15,但我不知道如何计算堆栈内存?是200 + 100?
答案 0 :(得分:0)
如果您正在尝试计算分配给函数中这些变量的空间量,请使用sizeof()
运算符。
请注意,数组是char *
的数组,它们是指向字符而不是字符的指针。
#include <stdio.h>
int main(void) {
size_t total=0;
size_t first_array_size=sizeof(char *[200]);
printf("first array: %zu\n",first_array_size);
total+=first_array_size;
size_t second_array_size=sizeof(char *[100]);
printf("second array: %zu\n",second_array_size);
total+=second_array_size;
size_t int_size=sizeof(int);
printf("int size: %zu * 2 = %zu\n",int_size,int_size*2);
total+=int_size*2;
printf("total=%zu\n",total);
return 0;
}
典型输出(在64位架构上):
first array: 1600
second array: 800
int size: 4 * 2 = 8
total=2408
结果可能会有所不同。
脚注:同样值得理解的是,分配给堆栈帧的空间量可能更大。 例如,传入的参数通常被复制到堆栈中,返回值以及表示在调用函数之后返回的执行点的指针也是如此。 还有对齐的复杂性。例如,在许多现代机器上,可以在变量之间留出空间以确保它们对齐。但是,优化可能会占用一些空间,具体取决于它如何重新排序变量。也有可能将值(特别是整数值)分配给寄存器而不占用堆栈上的空间。
最后,实现原则上可以在堆上分配数组。这当然是可变长度数组的可能实现,但我并不知道它对于固定大小的数组是严格禁止的。
答案 1 :(得分:0)
如果您正在做的不仅仅是尝试了解堆栈使用情况以及变量分配如何影响它,您还需要使用堆栈深度分析工具。这样的工具可以帮助您确定您的程序是否可能在任何可能的事件序列下溢出其堆栈(除了意外或无限制的递归)。您可以自己编写(我在C#中使用CCC编译的嵌入式程序,用于使用GCC和IAR编译器的M16C和MIPS目标),但它非常复杂,不适合初学者尝试。
为您的特定处理器和工具链(例如x86 / x64 / ARM /等和GCC / VisualStudio / IAR /等)寻找“堆栈使用分析器”或“堆栈使用情况分析工具”。
如果您正在使用GCC,则可以使用-fstack-usage
选项,但这仅为每个功能提供最大堆栈使用量。本身并不是非常有用,因为要验证程序是否会破坏其堆栈,您必须递归地遍历calltree以查看调用树的任何级别的最大堆栈深度。如果您还使用-Wstack-usage
选项,则可以在任何子程序的堆栈使用量可能超过指定的堆栈深度时收到警告,这比仅使用-fstack-usage
选项获得的信息更有用。 / p>