为什么执行完函数后,我的指针地址就变了

问题描述 投票:0回答:1

这是我的代码。我想将数据从一个内存区域复制到另一个内存区域。我知道这段代码不会检查数据的重叠,但我认为它不会影响指针的值

Ptr

void MemCopy2(uint8_t * Src, uint8_t * Dest, uint32_t Len)
{   
    uint32_t count;

        for (count = Len; count > 0; count--)
        {
            Dest[count-1] = Src[count-1];
        }

}

int main()
{

    uint32_t A[2] = { 0xABCD1234, 0x567890AB };
    uint32_t * Ptr = (uint16_t*)&A + 1;  // CD 
    
    printf("%d %d\n", Ptr, &A[0]);
    
    MemCopy2((uint8_t*)&A, (uint8_t*)Ptr, sizeof(A));

    printf("%d %d\n", Ptr, &A[0]);

    return 0;
}

我在执行函数之前和之后打印f

MemCopy2
,结果是

6487570 6487568
6444664 6487568

这意味着指针

Ptr
的值已经改变了

还是这段代码,如果我在

int i=6;
之前添加像
A[2]
这样的局部变量,现在的结果是

6487554 6487552
6487554 6487552

这意味着指针

Ptr
的值保持不变, 任何人都知道为什么会发生这种情况 我认为这是因为堆栈和取消堆栈将局部变量存储在寄存器中,类似的东西。

*编辑 为了避免重叠数据,我更改了顺序副本,而不是从 lsb 更改为数组的 msb ,如下图所示 enter image description here

c pointers memory-management variable-assignment
1个回答
0
投票

这是最小的例子:

#include <stdint.h>
#include <stdio.h>

void MemCopy2(const uint8_t *Src, uint8_t *Dest, uint32_t Len) {
    for (uint32_t count = Len; count > 0; count--)
        Dest[count-1] = Src[count-1];

}

int main(void) {
    uint32_t A[2] = { 0xABCD1234, 0x567890AB };
    uint32_t *Ptr = (uint32_t *) ((uint16_t *) &A + 1);
    printf("%p\n", Ptr);
    MemCopy2((uint8_t*)&A, (uint8_t*)Ptr, sizeof(A));
    printf("%p\n", Ptr);
    return 0;
}

输出为:

0x7ffeaf38ae82
0x7ffeaf385678

问题在于您将

sizeof(A)
字节复制到
A
的正偏移量中,这将导致缓冲区溢出。这是未定义的行为,我们的系统恰好会覆盖
Ptr

修复方法是使用写入偏移较少的数据:

#include <stdint.h>
#include <stdio.h>

void MemCopy2(const uint8_t * Src, uint8_t * Dest, uint32_t Len) {
    for (uint32_t count = Len; count > 0; count--)
        Dest[count-1] = Src[count-1];

}

int main(void) {
    uint32_t A[2] = { 0xABCD1234, 0x567890AB };
    size_t offset = 1;
    uint32_t *Ptr = (uint32_t *) ((uint16_t *) &A + offset);
    printf("%p\n", Ptr);
    MemCopy2((uint8_t*)&A, (uint8_t*)Ptr, sizeof(A) - sizeof(uint16_t) * offset);
    printf("%p\n", Ptr);
    return 0;
}

在非对齐边界访问阵列

A
将导致某些平台上的总线故障。

© www.soinside.com 2019 - 2024. All rights reserved.