在 C 编程中,有没有办法确定单个源代码文件对最终内存占用的贡献是多少?
让我们假设一个由源文件test1.c、test2.c、test3.c等组成的简单 C 程序。环境是 Linux 和编译器gcc。
使用objdump
和readelf
可以看到总占用空间以及二进制文件如何分布在.text
、.data
和.bss
段中。但是是否可以查看每个test1.c生成多少二进制代码,每个test2.c生成多少等?
问题标题和内容似乎指向不同的方向。
如果您的问题是您的应用程序在运行时每个源代码文件需要多少内存,那通常是无法确定的。它可能取决于您无法控制的外部输出,除非仅使用常量,否则您无法知道递归的深度(需要堆栈)或您需要多少动态内存,因为这些肯定取决于运行时信息——输入。
如果您的问题是最终二进制文件中有多少代码来自每个文件,那么您可以看看您是否有足够的兴趣。零 eth 近似值是检查.o
编译器生成的文件的大小。该近似值相当糟糕,因为链接器可以在链接阶段从目标文件中删除未使用的符号。然后,您可以更有趣地检查最终可执行文件中的符号,并在每个目标文件中查找这些符号。这将提供更好的信息,但需要更多的工作。
不,没有。大多数内存是在运行时分配的,不能从检查源文件中推断出来。例如,给定以下代码:
int n;
cin >> n;
char * p = new char[n];
检查源代码无法告诉您执行程序时将分配多少内存。
这是一个非常奇怪的问题。从表面上看,您只需要查看编译时生成的 .obj/.o 文件。就代码而言,这些将是每个模块的大小。
但是,这并没有考虑程序运行时分配的任何内存。它也没有考虑到当前未运行的程序部分不一定保存在内存中。
如果您担心编写大量代码并占用您所有的内存,请不要担心。这不可能发生。:)
不,基本上不是。
例如,获取两个都包含字符串的源文件"Hello, world\n"
。大多数链接器都能够折叠这些字符串文字。只剩下一个字符串文字,这应该如何解释?即使对于函数也会发生类似的事情。例如,std::vector<int>::push_back(int)
andstd::vector<long>::push_back(long)
可能会生成相同的可执行代码,而链接器可能只留下一个实例。
此外,再考虑vector<int>::push_back(int)
一下。它实际上来自一个标头,<vector>
该标头将包含在许多 .cpp 文件中。但是编译器通常根本不记录它——也test1.o
包含 test1.cpp 包含的所有内容。