指针向上和向下

发布于 2024-11-18 03:32:50 字数 1282 浏览 5 评论 0原文

指针向下

    int* ptrInt;
    char * ptrChar;
    void* ptrVoid;
    unsigned char indx;
    int sample = 0x12345678;

    ptrInt = &sample;
    ptrVoid = (void *)(ptrInt);
    ptrChar = (char *)(ptrVoid);

    /*manipulating ptrChar */
    for (indx = 0; indx < 4; indx++)
    {
        printf ("\n Value: %x \t Address: %p", *(ptrChar + indx), ( ptrChar + indx)); 
    }

输出:

 Value: 00000078         Address: 0022FF74
 Value: 00000056         Address: 0022FF75
 Value: 00000034         Address: 0022FF76
 Value: 00000012         Address: 0022FF77

问题: 为什么样本被分成char大小的数据?当进行指针运算时,它是如何获得其剩余值的呢? 这怎么可能?


指针向上转换

unsigned int * ptrUint;
void * ptrVoid;
unsigned char sample = 0x08;

ptrVoid = (void *)&sample;
ptrUint = (unsigned int *) ptrVoid;

printf(" \n &sample: %p \t ptrUint: %p ", &sample, ptrUint );
printf(" \n sample: %p \t *ptrUint: %p ", sample, *ptrUint );  

输出:

 &sample: 0022FF6F       ptrUint: 0022FF6F
 sample: 00000008        *ptrUint: 22FF6F08    <- Problem Point

问题: 为什么*ptrUint中有垃圾值?为什么垃圾值相似 去阻止?应该使用 malloc() 或 calloc() 来避免这个垃圾值吗?您建议采取什么样的补救措施来消除垃圾值?

Pointer Downcast

    int* ptrInt;
    char * ptrChar;
    void* ptrVoid;
    unsigned char indx;
    int sample = 0x12345678;

    ptrInt = &sample;
    ptrVoid = (void *)(ptrInt);
    ptrChar = (char *)(ptrVoid);

    /*manipulating ptrChar */
    for (indx = 0; indx < 4; indx++)
    {
        printf ("\n Value: %x \t Address: %p", *(ptrChar + indx), ( ptrChar + indx)); 
    }

Output:

 Value: 00000078         Address: 0022FF74
 Value: 00000056         Address: 0022FF75
 Value: 00000034         Address: 0022FF76
 Value: 00000012         Address: 0022FF77

Question:
Why was sample divided into char sized data? And when pointer arithmetic is performed, how was it able to get its remaining value?
How this was possible?


Pointer Upcast

unsigned int * ptrUint;
void * ptrVoid;
unsigned char sample = 0x08;

ptrVoid = (void *)&sample;
ptrUint = (unsigned int *) ptrVoid;

printf(" \n &sample: %p \t ptrUint: %p ", &sample, ptrUint );
printf(" \n sample: %p \t *ptrUint: %p ", sample, *ptrUint );  

Output:

 &sample: 0022FF6F       ptrUint: 0022FF6F
 sample: 00000008        *ptrUint: 22FF6F08    <- Problem Point

Question:
Why is it that there is a garbage value in *ptrUint? Why is the garbage value similar
to ptrUint? Should malloc() or calloc() be used to avoid this garbage value? What kind of remedy would you suggest to remove the garbage value?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

你不是我要的菜∠ 2024-11-25 03:32:50

在第一个示例中,您使用的是 char 指针,因此一次将访问一个字节的数据。内存是可字节寻址的,因此当您向指针加一时,您将访问下一个更高的内存地址。这就是 for 循环所发生的情况。使用字节指针告诉编译器仅访问单个字节,当您使用 %p 打印时,其余位将显示为 0。

在第二个示例中,我认为发生的情况是为样本字节分配了一个字节,然后将以下 4 个字节分配给 ptrUint。因此,当您获取从 Sample 的内存地址开始的值并将其转换为 4 字节指针时,您只会看到 Sample 中的值加上 ptrUint 的前 3 个字节。如果将其转换为 char 指针并打印,则在输出中只会看到 8。

In the first example, you are using a char pointer so the data is going to be accessed a byte at a time. Memory is byte addressable, so when you add one to a pointer, you will access the next higher memory address. This is what is happening with the for loop. Using a byte pointer tells the compiler to access only the single byte, and rest of bits will show up as 0 when you are printing with %p.

In the second example, I think what is happening is that one byte is allocated for the sample byte, then the following 4 bytes were allocated to the ptrUint. So when you get the value starting at the memory address of sample and converting it to a 4 byte pointer, you just see the value in Sample plus the first 3 bytes of the ptrUint. If you cast this to a char pointer, and print, you would only see 8 in the output.

故事还在继续 2024-11-25 03:32:50

这些不是向上转型和向下转型,这意味着某种继承层次结构。

在第一个示例中,您将指向整数的指针视为指向字符的指针。递增 int 指针会加 4,递增 char 指针会加 1(假设 32 位整数和 8 位字符)。取消引用它们分别生成 int 和 char。因此,碎片化为字节。

在第二个示例中,您将名为 example 的 unsigned char 变量视为指向 int 的指针,并取消引用它。您实际上是从 0x08 内存地址读取垃圾。我想你忘了一个&。您还将一个 1 字节 char 和一个 4 字节 int 传递给第二个 printf,而不是 4+4 字节,这会弄乱 printf,从堆栈中读取的字节比您给他的多 3 个字节。巧合的是,这是第一次调用 printf 时给出的 ptrUint 值的一部分。使用 %c 而不是 %p 应该可以修复它。

These aren't upcasts and downcasts, that would imply some kind of inheritance hierarchy.

In your first example you treat a pointer to an integer like if it was a pointer to char(s). Incrementing a pointer to int adds 4 to it, incrementing a pointer to char adds 1 to it (assuming 32 bit ints and 8 bit chars). Dereferencing them makes an int and a char, respectively. Hence the fragmentation into bytes.

In your second example you treat the unsigned char variable called sample as if it were a pointer to int, and dereference it. You are essentially reading garbage from the 0x08 memory address. I suppose you forgot a &. You are also passing a 1 byte char and a 4 byte int to the second printf, instead of 4+4 bytes, that messes up printf, reading 3 bytes more from the stack than you have given him. Which coincidentally is part of the ptrUint value given to the first call of printf. Using %c instead of %p should fix it.

无畏 2024-11-25 03:32:50

其他答案已经解释了为什么您会看到您所看到的内容。

我要补充一点,你的第二个例子依赖于未定义的行为。取消引用指向最初不是 int 的数据的 int * 是无效的。 IE:

char x = 5;
int *p = (int *)&x;
printf("%d\n", *p);  // undefined behaviour

The other answers have already explained why you're seeing what you're seeing.

I will add that your second example relies on undefined behaviour. It is not valid to dereference an int * that points to data that wasn't originally an int. i.e.:

char x = 5;
int *p = (int *)&x;
printf("%d\n", *p);  // undefined behaviour
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文