如何将数组名称存储在内存中?
例如,如果我写:
char arr[10];
数组项存储在内存中,从虚拟地址&arr[0]
开始,实际上是arr的值,但是arr
本身存储在哪里?
静态多维数组的行也是如此:
char arr[10][20];
arr本身也是arr [0],arr [1] .... arr [9]本身都没有地址。
那么名称存储在哪里?
答案 0 :(得分:5)
如果您指的是您声明的文字名称,除非您使用调试符号-g
进行编译,否则通常会将其编译出来。
如果在堆栈上声明了某些内容,则机器代码通常将数组元素称为与帧指针$ebp
的偏移量。
要回答您的隐含问题,对于堆栈中的数组,它不存在。机器代码不知道arr
是什么。它只知道你正在使用偏移量(代码中的索引)来寻址存储区域。
这个问题对于堆上的数组更有意义,因为现在你有一个指针(它有自己的地址),以及保存实际数组的存储器(存在于堆中,并存储在指针内)
请考虑以下代码。
char* arr = malloc(5);
假设您使用调试符号进行编译,如果查看&arr
内的gdb
,您将看到存储指针arr
的地址。
如果在堆栈上创建一个指向数组的单独指针,则可以演示相同的内容。
char arr[10];
char* ptr = arr;
在这里,您会看到ptr
具有单独的存储空间(p &ptr
),并将arr
的地址保留为其值,但&arr
本身等于第一个元素的地址。
答案 1 :(得分:3)
编译时,数组的名称会丢失。它仅供参考。元素存储在堆栈中,但编译后数组名称将丢失,除非您在调试中没有-g选项。
答案 2 :(得分:3)
arr本身也是arr [0],arr [1] .... arr [9]本身都没有地址。
arr
只是数组的基址。通过向该地址添加偏移来定位各个元素。编译代码后,除了调试之外,数组的名称是没有用的。
答案 3 :(得分:3)
正如其他人所说,您的变量名称在源代码中是 symbols 。它们没有被编译器翻译成机器代码,因此无处可寻找,尽管它们可以使用适当的选项附加到您的可执行文件(例如gcc中的-g
,这将生成以调试目的调试操作系统本机格式的信息。
在机器代码中,变量由内存位置引用,可以是各种各样的,具体取决于机器和编译器:
函数参数和局部变量将取决于calling conventions和优化,并且通常(在x86上)从特殊寄存器%ebp(称为基指针)计算的地址和偏移量。它们也可以作为寄存器直接传递(例如,第一个参数可以转换为通用寄存器),或者作为内存中不同的特殊地址(特定于函数)的偏移量。
取消引用指针时,变量的地址是从内存中间接获得的(如果使用动态内存分配,例如malloc
,则可能仅在运行时可用)。
底线,在机器代码中,您通常找不到变量名(从C编译时)。相反,你有寄存器和地址(或者,确切地说,你必须猜测的数字常量和计算值是地址),这是为什么只通过查看二进制来理解代码的原始含义是一个难题(尽管尝试将二进制文件反编译为汇编代码会产生问题。)