简体   繁体   English

需要帮助了解指针算法

[英]Need help understanding pointer arithmetic

I'm having troubles understanding pointer arithmetic or how memory is assigned. 我在理解指针算术或如何分配内存时遇到了麻烦。 In the code snippet below, I am trying to access the value of 'size = 1' which is located 8 bytes before 'test', but I don't get size's value and the value is not random. 在下面的代码段中,我尝试访问“大小= 1”的值,该值位于“测试”之前的8个字节处,但是我没有获得大小的值,并且该值不是随机的。 So I may have an issue with understanding bytes sizes. 所以我可能对理解字节大小有疑问。 If void*, long, and char are 8 bytes should it matter when using pointer arithmetic? 如果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;
}

The code works when main moves forward from what()'s void* 'pointer: 当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;
}

Your code is not locating *size eight bytes before *test : 您的代码未在*test之前定位*size八个字节:

size = (long*)&arrayOfCrap[28];

arrayOfCrap is char arrayOfCrap[100] so arrayOfCrap[28] is the char at offset 28 and arrayOfCrap[29] is the char at offset 29. arrayOfCrap是char arrayOfCrap[100]因此arrayOfCrap[28]是偏移量28的字符, arrayOfCrap[29]是偏移量29的字符。

The reason test++ works is that test is of type long* , so incrementing it actually moves to the next position for a long, whereas incrementing a char* or using an index on a char array gives you the next position for a char . 究其原因test++工作原理是,测试的类型为long* ,因此增加它实际上移动到下一个位置久,而递增char*或字符数组上使用索引给你一个字符的下一个位置。

You could also do one of these: 您还可以执行以下操作之一:

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)];
}

By the way, its not necessarily safe to take a pointer to just any memory location and treat it as a pointer to another type. 顺便说一句,将一个指针指向任何内存位置并将其视为指向另一种类型的指针并不一定安全。 Some platforms require some types to be 'aligned', or to have those types exist only at addresses that are multiples of a certain value. 一些平台要求某些类型是“对齐的”,或者仅在特定值倍数的地址上存在那些类型。 On those platforms reading or writing to an unaligned object may crash (bus error) or otherwise have undefined behavior. 在那些平台上,读取或写入未对齐的对象可能会崩溃(总线错误)或具有未定义的行为。 Also, some platforms may not crash or behave incorrectly, but have much better performance when reading/writing aligned objects. 同样,某些平台可能不会崩溃或行为不正确,但是在读取/写入对齐的对象时具有更好的性能。 I know this is completely beside the point of your experimentation, but it's something you should know for real code. 我知道这完全不适合您的实验,但是对于真正的代码,您应该知道这一点。 Here's an example of what not to do in real code: 以下是在实际代码中不可以执行的操作的示例:

int read_int(char *&c) {
  int out = *(int*)c; // c may not be properly aligned!
  c += sizeof(int);

  return out;
}

Unfortunately on a common platform, x86, unaligned access is usually just slow rather than something that will always cause a crash, so users of that platform have to be especially careful. 不幸的是,在通用平台x86上,未对齐的访问通常只是缓慢而已,而并非总是会导致崩溃的,因此该平台的用户必须特别小心。

When you increment a pointer, it increments not by the pointer size, but by the size of the type of the pointer. 当您增加一个指针时,它不会增加指针大小,而是增加指针类型的大小。 A char* pointer increments by sizeof(char) , a long* pointer increments by sizeof(long) char*指针按sizeof(char)递增, long*指针按sizeof(long)递增

sizeof(char *) , sizeof(long *) should be both the same size (generally 4 bytes on 32-bit systems, 8 bytes on 64-bit systems). sizeof(char *)sizeof(long *)的大小都应相同(在32位系统上通常为4个字节,在64位系统上通常为8个字节)。

However, sizeof(char) and sizeof(long) are not the same. 但是, sizeof(char)sizeof(long)不同。

You are confusing your pointer size with the integer size. 您将指针大小与整数大小混淆了。

#include <iostream>
using namespace std;

int main()
{
    cout << "\n sizeof(char*)   " << sizeof(char *);
    cout << "\n sizeof(char)    " << sizeof(char);
    cout << "\n sizeof(long*)   " << sizeof(long *);
    cout << "\n sizeof(long)    " << sizeof(long);
}

See it in action here: http://ideone.com/gBcjS 在此处查看其运行情况: http : //ideone.com/gBcjS

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM