c - 如何在不初始化变量的情况下读取整个内存堆栈?

标签 c windows memory-management

每个进程获得 4 GB 的虚拟地址空间,而在这 4 GB 中,用户空间获得 2 GB。在这 2 GB 中,我想读取操作系统分配给进程的整个内存堆栈。

假设我在堆栈上声明了一个大小为 2000,000 ( char chrArray[2000000]; ) 的局部数组。我想问几个问题。

1) 使用 gcccygwin,我可以在没有初始化的情况下读取它的内容,但它的内容大部分是空的(我使用了 %c 将数组打印到文件中)或此数组末尾的一些垃圾数据。我在垃圾数据中提取了一个字符串并在内存转储中查找它(使用 DumpIt 工具获取)但该字符串不存在于内存转储中。

我的问题是这些垃圾数据来自哪里?它位于硬盘中吗?

2) 我想过使用 fork() 在每个子进程中声明 char 数组,但我猜,它复制父进程的整个地址空间并使用 Copy-on-Write 技术,所以它似乎没有用。我的解释对吗?

3) 我想要的是声明一个大数组,每次都映射到一些新的物理内存地址。这是可以实现的吗?如果可以,如何实现?

通过重复这个过程,我想扫描整个内存。

我多次尝试使用 bash 脚本来运行这个程序,但它总是从相同的虚拟基地址开始。

我尝试运行一个 for 循环,它声明(比方说)10 个字符数组,但通过打印它们的基地址,我看到所有数组的地址相同。

我正在使用 Windows 7C 程序,我认为我缺乏一些必需的操作系统知识。

谢谢。

附言如果有人好奇我为什么要这样做,我正在做这方面的研究。

最佳答案

Suppose I declare a local array of size 2000,000 ( char chrArray[2000000]; )

这很危险。如果堆栈用完,您的程序就会崩溃。

some junk data at the end of this array.

堆栈向下增长,因此数组的末尾(较高部分)对应于堆栈的较旧部分。当你的程序启动时,数据被清零,当你的程序运行时,它会将数据写入堆栈。因此,“垃圾数据”只是您调用的函数中剩余的局部变量和堆栈帧的其他位。 (大多数操作系统使用专门的写时复制技术将您的进程内存归零——我说“专门”是因为当您知道整个 block 都为零时复制一 block 内存很容易。)

Was it located in hard-disk?

来自硬盘的数据只是故意出现在你的内存空间中。当您的进程重用另一个进程的内存时,内存首先被清零。

I thought of using fork() to declare char array in each child process but I guess, it copies the whole address space of parent process and uses Copy-on-Write technique, so it seems not useful. Am I right at this interpretation?

这是带标签的 Windows,它没有 fork(),除非您使用 Cygwin。我不知道 Cygwin 的实现。我不确定您想要完成什么,或者您期望什么,但这正是 fork() 应该表现的方式。 fork() 调用复制整个进程,包括内存。

What I want is to declare an array of big size and every time it is mapped to some new physical memory addresses. Is this achievable and if yes, how?

用户空间程序不使用物理内存地址,只能使用虚拟内存地址。不,这是不可能的。

更糟糕的是,假设您在虚拟地址 1000 处分配了一个数组 char arr[10000],并且假设虚拟地址 1000 对应于物理地址 6000。

  • &arr[0] 的地址是虚拟地址 1000 和物理地址 6000...除非您的进程被换出,此时它没有 物理地址。所以物理地址并不总是存在。

  • 当您的进程换回时,&arr[0] 仍将是虚拟地址 1000,但它可能是物理地址 6000、8000 或 999000...谁知道呢?

  • &arr[1000] 的地址始终是虚拟地址 2000,但它可能是物理地址 10000 或 85000 或其他完全不同的地址...谁知道呢?

进一步阅读:您可能希望阅读操作系统的“虚拟内存”子系统。

关于c - 如何在不初始化变量的情况下读取整个内存堆栈?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12878497/

相关文章:

c - 使用 Lua C API 选择带有选择器字符串的嵌套值

在 ANSI c80 中将 while 循环更改为 for 循环

python - 为什么 stdbuf 对 Python 没有影响?

c++ - 遍历 2D vector 以从内存中删除对象

python - Ctypes - 从使用 ctypes 的 python 代码获取 C 回溯

asp.net - 如何使用自托管 ASP.NET Core 2 应用程序 (httpsys) 进行 HTTPS (SSL)

c - _beginthread 的第二个参数 stack_size 是什么意思?

c++ - 从 Windows 上的 QCamera 获取支持的像素格式

C内存映射

c - 用于在 C 中返回值的空闲内存