我在理解指针运算或内存分配方式时遇到了麻烦。在下面的代码片段中,我试图访问位于“test”之前 8 个字节的“size = 1”的值,但我没有获得 size 的值并且该值不是随机的。所以我可能无法理解字节大小。如果 void*、long 和 char 是 8 个字节,那么在使用指针运算时有什么关系吗?
#include <iostream>
using namespace std;
char arrayOfCrap[100];
void * what(){
long * size ;
size = (long*)&arrayOfCrap[28];
*size = 1;
return ((void*) &arrayOfCrap[29]);
}
int main(){
long * test;
test = (long*)what();
*test = 1221;
cout << "Value of test: " << *test << endl;
cout << "Long number before test: " << *(test-1) << endl;
}
当 main 从 what() 的 void* 指针向前移动时,代码有效:
#include <iostream>
using namespace std;
char arrayOfCrap[100];
void * what(){
long * size ;
size = (long*)&arrayOfCrap[28];
*size = 1;
return ((void*) &arrayOfCrap[28]); //change from above
}
int main(){
long * test;
test = (long*)what();
test++; //change from above
*test = 1221;
cout << "Value of test: " << *test << endl;
cout << "Long number before test: " << *(test-1) << endl;
}
最佳答案
您的代码未在 *test
之前定位 *size
八个字节:
size = (long*)&arrayOfCrap[28];
arrayOfCrap 是 char arrayOfCrap[100]
所以 arrayOfCrap[28]
是偏移量 28 处的字符,arrayOfCrap[29]
是字符在偏移量 29 处。
test++
工作的原因是 test 是 long*
类型,因此递增它实际上移动到下一个位置 long,而递增 char *
或在字符数组上使用索引为您提供字符的下一个位置。
您也可以执行以下操作之一:
void * what(){
long * size ;
size = (long*)&arrayOfCrap[28];
*size = 1;
return size+1;
}
void * what(){
long * size ;
size = (long*)&arrayOfCrap[28];
*size = 1;
return ((void*) &arrayOfCrap[28 + sizeof(long)];
}
顺便说一句,将指向任意内存位置的指针视为指向另一种类型的指针并不一定安全。某些平台要求某些类型“对齐”,或者让这些类型仅存在于某个值的倍数的地址处。在那些平台上读取或写入未对齐的对象可能会崩溃(总线错误)或以其他方式出现未定义的行为。此外,某些平台可能不会崩溃或行为不正确,但在读取/写入对齐对象时具有更好的性能。我知道这完全不符合您的实验目的,但对于实际代码而言,这是您应该了解的内容。以下是在实际代码中不应该做的事情的示例:
int read_int(char *&c) {
int out = *(int*)c; // c may not be properly aligned!
c += sizeof(int);
return out;
}
不幸的是,在通用平台 x86 上,未对齐的访问通常很慢,而不是总是会导致崩溃,因此该平台的用户必须特别小心。
关于c++ - 需要帮助理解指针算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11142576/