数组本身的名称,存储在哪里

时间:2014-04-29 06:43:33

标签: c memory-management

如何将数组名称存储在内存中?

例如,如果我写:

char arr[10];

数组项存储在内存中,从虚拟地址&arr[0]开始,实际上是arr的值,但是arr本身存储在哪里?

静态多维数组的行也是如此:

char arr[10][20];

arr本身也是arr [0],arr [1] .... arr [9]本身都没有地址。

那么名称存储在哪里?

4 个答案:

答案 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编译时)。相反,你有寄存器和地址(或者,确切地说,你必须猜测的数字常量和计算值是地址),这是为什么只通过查看二进制来理解代码的原始含义是一个难题(尽管尝试将二进制文件反编译为汇编代码会产生问题。)