数组在哪里存储在内存中?

时间:2019-06-19 13:14:22

标签: c

我知道全局变量存储在内存中,局部变量保存在堆栈中,每次使用后都会破坏堆栈。

但是我不知道数组如何保存在内存中。 我试图声明一个全局数组:

  int tab[5]={10,9,12,34,30};

最后,我读取了存储器的内容,我的意思是,在执行代码之后,我读取了存储器的内容(例如,我在微控制器上工作,我知道数据在哪里)当我声明一个全局变量时,例如a = 10;当我读取内存的内容时,我在内存中找到了值10,但找不到表10、9、12、34、30的内容

我想了解数组内容保存在内存中的什么位置?

我在Aurix Infineon上工作,我使用Hightec作为编译器,我直接在aurix上执行我的代码,我读到这样的记忆:

const volatile unsigned char * mem_start = 0xd0000000;
#define size ((ptrdiff_t) 0xfff)
unsigned char bufferf [size];
code ();
main(){
    ... 
    for (int e = 0; e < sizeof (bufferf); e ++) 
        bufferf [e] = * (mem_start + e); // read memory
}

3 个答案:

答案 0 :(得分:1)

global variable is stored in memory, and the local variable is saved in the stack

这是错误的。

有时全局变量不仅保存在静态存储器中,而且还保存在寄存器中。

如果函数是递归的,则编译器可以选择是否使用堆栈。如果该函数是尾部递归,则无需使用堆栈,因为该函数返回后无需继续,因此可以将当前帧用于下一次调用。

有一些机械方法可以以连续传递样式和等效形式it is evaluated stackless转换代码。

有许多数学计算模型,但并非全部使用堆栈。代码可以converted from one model to other,在评估后保持相同的结果。

您从70年代,80年代写的书中获得了这些信息,与此同时,代码评估的过程有了很大的改进(使用30年代理论上的方法,但如今已在系统中实现)。

答案 1 :(得分:1)

关于将数组或实际上任何变量存储在何处的问题的答案取决于您是在考虑抽象机器还是实际硬件。 C标准规定了事物在抽象机器上的工作方式,但是如果 observable effect 相同,那么符合要求的编译器可以在实际硬件上自由地做其他事情(例如,由于优化)。 >

(在抽象机上,数组通常存储在与在相同范围内声明的其他变量相同的位置。)

例如,变量可以放在寄存器中而不是堆栈中,或者可以完全优化掉。作为程序员,您通常不必在意这一点,因为您也可以只考虑抽象机。 (诚​​然,在某些情况下,您确实会对此有所关心,并且在RAM非常有限的微控制器上,原因之一可能是您必须非常节俭地使用堆栈等)。

关于您读取内存的代码:它可能无法工作。如果size是变量可用的内存大小,则无法将数组bufferf[size]容纳在该内存中与其他所有内容一起使用。

幸运的是,不需要将内存内容复制到单独的缓冲区。考虑您的行bufferf[e] = *(mem_start + e) –由于您已经可以从e处的内存中读取任意索引mem_start,因此可以使用*(mem_start + e)(或者更好的是mem_start[e],这完全等效)直接在您将使用bufferf[e]的任何地方!只需将mem_start视为指向size字节数组的第一个元素即可。

还要注意,如果您以编程方式搜索数组tab的内容,则其元素为int,因此它们每个都超过一个字节–您不会简单地找到五个相邻的字节具有这些值的字节。

(然后,您也可以只获取tab[0]的地址并找出其存储位置,即((unsigned char *) tab) - mem_starttabmem_start中的索引。但是,由于上述优化,此处观察可能会改变某些情况。)

答案 2 :(得分:0)

该程序可能使您更接近所需的内容:

int tab[] = {10, 9, 12, 34, 30};

// Used to get the number of elements in an array
#define ARRAY_SIZE(array) \
    (sizeof(array) / sizeof(array[0]))

// Used to suppress compiler warnings about unused variables
#define UNUSED(x) \
    (void)(x)

int main(void) {
    int *tab_ptr;
    int tab_copy[ARRAY_SIZE(tab)];
    tab_ptr = tab;
    UNUSED(tab_ptr);
    for (int index = 0; index < ARRAY_SIZE(tab_copy); index++) {
        tab_copy[index] = tab[index];
    }
    return 0;
}

我没有Hightec环境可以对此进行测试,也没有Aurix可以运行它。但是,这可能会为您提供一个起点,帮助您获得所需的信息。

看起来Infineon Aurix是32位的Little-endian计算机。这意味着int的宽度为32位,而第一个字节将存储值的前8位。例如,值10的存储方式如下:

0a 00 00 00

如果您尝试将此存储器读取为char,则会得到0x0a0x000x000x00