pananning 发表于 2024-8-4 00:45

为什么两次输出值不一样

本帖最后由 pananning 于 2024-8-4 00:47 编辑

#include <iostream>
#include <vector>
#include <windows.h>

typedef struct A {
    DWORD a;

} A, * PA;

typedef struct k {

    DWORD unk0;
    DWORD unk1;
    WCHAR Guid;
    DWORD unk2;
    DWORD unk3;
    DWORD Policy;
    DWORD64 KeyLen;
    DWORD64 Key2Len;
    DWORD64 Key3Len;
    DWORD64 Key4Len;
    PA Key;

} k, * Pk;


class B
{
public:
    MasterFile()
    {
      _binFile.resize(256);
      for (int i = 0; i < 256; ++i) {
            _binFile = i;
      }
    }

    BOOL File();


    std::vector<BYTE> _binFile;
    Pk _Keys;
};

BOOL B::File() {
    _Keys = (Pk)_binFile.data();

    std::wcout << *(DWORD*)&_binFile << std::endl;

    _Keys->Key = (PA)(&_binFile);

    std::wcout << *(DWORD*)&_binFile << std::endl;

    return TRUE;
}

int main() {
    B mf;
    mf.File();

    return 0;
}

中间只是让一个指针指向这个地址,并没有改变内存数据,为什么两次输出值就不一样了呢

丶峰宇 发表于 2024-8-4 00:54

以下ChatGPT mini4o回复结果

在你的代码中,两次输出值不一样是因为 `_Keys->Key` 的赋值操作修改了 `_binFile` 的内容。具体来说,以下这行代码:

```cpp
_Keys->Key = (PA)(&_binFile);
```

将 `_Keys->Key` 指向 `_binFile` 的地址。但是由于 `_Keys` 是 `_binFile` 的一部分,这个赋值操作会修改 `_binFile` 的内容。

为了更清楚地解释这个问题,我们可以深入了解一下内存布局和指针操作的细节。

### 内存布局和指针操作

1. **初始化 `_binFile`**
   ```cpp
   _binFile.resize(256);
   for (int i = 0; i < 256; ++i) {
       _binFile = i;
   }
   ```

   `_binFile` 被初始化为 256 字节的向量,每个字节的值等于其索引。

2. **设置 `_Keys` 指针**
   ```cpp
   _Keys = (Pk)_binFile.data();
   ```

   `_Keys` 被设置为指向 `_binFile` 的开始位置。因为 `Pk` 是一个结构体指针,所以 `_Keys` 指向 `_binFile` 的前几个字节被解释为 `k` 结构体。

3. **第一次输出**
   ```cpp
   std::wcout << *(DWORD*)&_binFile << std::endl;
   ```

   这行代码输出 `_binFile` 从第 128 字节开始的 `DWORD` 值,即 `0x80818283`。

4. **修改指针**
   ```cpp
   _Keys->Key = (PA)(&_binFile);
   ```

   这里将 `_Keys->Key` 指向 `_binFile` 的地址。但是,由于 `_Keys` 是 `_binFile` 的一部分,这个操作实际上修改了 `_binFile` 的内容。在这种情况下,`_Keys->Key` 的赋值操作可能会改变 `_binFile` 的内容,特别是与 `Key` 成员变量在内存中的位置相关的内容。

5. **第二次输出**
   ```cpp
   std::wcout << *(DWORD*)&_binFile << std::endl;
   ```

   由于 `_Keys->Key` 的赋值操作,`_binFile` 的内容可能被改变,因此第二次输出的值不再是原来的 `0x80818283`。

### 解决方案

如果你的意图是保持 `_binFile` 的内容不变,可以尝试以下方法之一:

1. **不要直接修改指针**:避免直接修改 `_Keys->Key`,而是使用临时变量来进行操作。
   
2. **使用深拷贝**:在需要修改 `_binFile` 的内容时,使用深拷贝来保护原始数据。

3. **更改设计**:如果可能,重新设计数据结构和操作方式,避免这种指针导致的副作用。

根据你的代码和需求,建议在修改指针前保存 `_binFile` 的内容,并在需要时恢复,以确保不会意外修改原始数据。

我心飞翔1995 发表于 2024-8-4 08:07

一、本版只限于发布编程技术和源码分享有关的求助、讨论或则学习记录,学习记录贴请勿短时间刷多个主题,可通过编辑和回复进行更新,无法回复编辑可发新帖。禁止使用ChatGPT或其他AI生成的答案解答问题,不准发布与问题无关的回复 。
偷懒也不是这种偷懒啊,版规都说了不允许AI生成了,还敢违规。起码自己编辑一下,用自己的话说一遍。

pananning 发表于 2024-8-4 09:58

丶峰宇 发表于 2024-8-4 00:54
以下ChatGPT mini4o回复结果

在你的代码中,两次输出值不一样是因为 `_Keys->Key` 的赋值操作修改了 `_b ...

ai就不要回复了,我也会用ai

nob 发表于 2024-8-4 11:35

其实AI也说到点上了。
你说“中间只是让一个指针指向这个地址,并没有改变内存数据”并不确切,毕竟你改变了_Keys->Key的值。
而 _Keys = (Pk)_binFile.data(); 使_Keys与_binFile指向了同一位置,当你修改成员Key的值时也就修改了_binFile的部分数值。
所以两次的结果自然也就不同了。

pananning 发表于 2024-8-4 12:10

nob 发表于 2024-8-4 11:35
其实AI也说到点上了。
你说“中间只是让一个指针指向这个地址,并没有改变内存数据”并不确切,毕竟你改变 ...

谢谢,似乎明白了

yes2 发表于 2024-8-5 08:57

由于结构体k的对齐,PA Key成员的偏移刚好是128。
_Keys = (Pk)_binFile.data();这里_Keys相当于指向了_binFile数组的起始,_Keys->Key = xxx就会改变_binFile数组128偏移处的4个字节的值
页: [1]
查看完整版本: 为什么两次输出值不一样