重叠指针

时间:2015-01-08 20:43:45

标签: c

我有一个案例,其中uint64_t*char*(6个字符长)和uint16_t*指向地址x,{{分别为1}}和x+2。所以如果char *指向"这个我"那么x应指向值uint16_t* dec,而0应指向值uint64_t* dec。

但是当我看到这些值时,115, 588, 096, 157, 780我得到0分,我不明白为什么会这样。有人可以解释一下吗?

编辑(添加代码):

uint64_t

,输出为:

FILE *file = fopen("/Users/Justin/Desktop/test.txt", "rb");
uint64_t *window = malloc(8);
char *buffer = (char*)(window+2);
uint16_t *data = (uint16_t*)window;
uint16_t *read = (uint16_t*)(window+6);

fread(buffer, 6, 1, file);

printf("%p\n", window);
printf("%p\n", buffer);
printf("%p\n", data);
printf("%p\n", read);
printf("%s\n", buffer);
printf("%llu\n", *window);

3 个答案:

答案 0 :(得分:6)

你被指针数学绊倒了。

window声明为uint64_t *时,window + 2不会将地址增加两个字节;它将它递增2 * sizeof(uint64_t)(即十六个字节)。结果,您正在查看的内存未初始化(实际上,它位于分配的块之外)。

如果您确实希望地址增加两个字节,那么在向其添加2之前,您需要将指针强制转换为char *

char *buffer = ((char *) window) + 2;

答案 1 :(得分:2)

我认为你误解了+2在这里的作用:

uint64_t *window = malloc(8);
char *buffer = (char*)(window+2);

有助于可视化我们从malloc获取的数据,使用|来帮助显示8字节边界:

|-------|-------|-------|-------|-------|-------|-------|-------
^
window

现在,buffer并未在window之前指出两个字节。它指出了前面两个uint64_t。或者换句话说,((char*)window) + 2 * sizeof(*window)

|-------|-------|-------|-------|-------|-------|-------|-------
^               ^
window          buffer

然后你进入

|-------|-------This i--|-------|-------|-------|-------|-------
^               ^
window          buffer

如果您想提前指出两个字节,则必须将2添加到char*

char* buffer = ((char*)window) + 2;

答案 2 :(得分:0)

除了@duskwuff指出的指针数学问题和@Barry澄清之外,还有另一个问题。您得到的答案取决于运行此代码的计算机体系结构。

在big-endian机器上你会得到一个答案,在小端机器上你会得到不同的答案。

哦,还有一件事。使用%s编写缓冲区非常危险。如果从文件读取的数据中没有零字节,它将在内存中漫游,直到找到它为止。