开始研究Ulrich Dreppers“每个程序员应该了解的关于记忆的内容”[1]系列我试图重现
部分中提供的示例时遇到困难3.3.2缓存效果的测量
据我所知,应该在堆栈上分配结构,因为它们一个接一个地存储在内存中。用小程序验证:
#include <stdio.h>
#include <stdlib.h>
#define NUMPAD 0
struct listelement
{
struct listelement *next;
long int padding[NUMPAD];
};
typedef struct listelement elem;
int main()
{
int size_elem = sizeof(elem);
printf("Size of a list elem: %i\n", size_elem);
elem _1, _2, _3;
_1.next = &_2;
_2.next = &_3;
_3.next = &_1;
elem *first, *last, *curr;
first = &_1;
last = &_3;
curr = &_1;
int k=0;
while(1)
{
printf("Element at %p", curr);
for (int i=0; i<NUMPAD; i++)
{
(curr->padding)[i] = i+k;
printf("%ld ", (curr->padding)[i]);
}
printf("\n");
if (curr == last)
break;
k++;
curr = curr->next;
}
return 0;
}
运行程序时输出为:
Size of a list elem: 8
Element at 0x7fff5fbff540
Element at 0x7fff5fbff530
Element at 0x7fff5fbff520
内存地址之间的差异是16为什么不是8?当增加NUMPAD时,差异似乎会增长得更多,例如对于NUMPAD = 2,我得到的差异为511.
我在运行OSX 10.6 64bit的macbook pro上进行了测试。
[1] http://lwn.net/Articles/252125/
更新:我还使用递增/递减指针。它似乎在32位模式下工作,但在64位模式下不工作。添加代码
first--;
printf("first-- %p\n", first);
if (first == &_2) {
printf("Decrementing works.\n");
}
macbook:blah nils$ gcc -m32 -DNUMPAD=0 -g -std=c99 -o blah blah.c && ./blah
Size of a list elem: 4
Element at 0xbffff5b8
Element at 0xbffff5b4
Element at 0xbffff5b0
first-- 0xbffff5b4
Decrementing works.
macbook:blah nils$ gcc -DNUMPAD=0 -g -std=c99 -o blah blah.c && ./blah
Size of a list elem: 8
Element at 0x7fff5fbff530
Element at 0x7fff5fbff520
Element at 0x7fff5fbff510
first-- 0x7fff5fbff528
我想知道这是否有意义......也许我应该将所有结构放入数组中。
答案 0 :(得分:2)
强制警告:一般来说,你不应该对自变量的内存中的相对位置做出任何假设(即,未包含在数组或结构中的那些变量)。允许编译器在其认为合适时在堆栈上布置变量,这取决于struct成员的对齐限制。
那就是说,如果你改变的话,我想你会发现:
printf("Element at %p", curr)
到
printf("Element at %p\n", curr)
你的输出会更有意义。
答案 1 :(得分:1)
答案 2 :(得分:0)
零长度数组调用未定义的行为,所以你很幸运它没有编译到system("rm -rf /");
......
答案 3 :(得分:0)
更改
printf("%ld ", (curr->padding)[i]);
到
printf("\t%ld ", (curr->padding)[i]);
然后再试一次 - 明白了吗?
以下是我的结果(在32位计算机上),其中包含NUMPAD
的各种值。
test $ gcc -std=c99 -DNUMPAD=0 test.c && ./a.out
Size of a list elem: 4
Element at 0xbfd84df8
Element at 0xbfd84df4
Element at 0xbfd84df0
test $ gcc -std=c99 -DNUMPAD=1 test.c && ./a.out
Size of a list elem: 8
Element at 0xbff7eff4 0
Element at 0xbff7efec 1
Element at 0xbff7efe4 2
test $ gcc -std=c99 -DNUMPAD=2 test.c && ./a.out
Size of a list elem: 12
Element at 0xbf9ea260 0 1
Element at 0xbf9ea254 1 2
Element at 0xbf9ea248 2 3