我知道通常在 32 位机器中,常规 C 程序中使用的指针大小是 32 位。那么在具有 PAE 的 x86 系统中呢?
我正在构建一个数据结构,每2或3位设置为64位整数.
如果我可以交替地在这个结构中存储指针(当它们是树中的终端节点,但这不相关时)对我来说会很方便.
出于我的表示(保证设置最高或第二高位)的目的,如果可以假设指针永远不会设置其最高的两位,即此断言成立:
void *sixty_four_bit_pointer = a_valid_address();
bool always_zero = 0xC000000000000000 & sixty_four_bit_pointer;
Run Code Online (Sandbox Code Playgroud)
那我就可以做到这一招!
我使用ReadProcessMemory函数从地址空间读取数据.我尝试从所有具有MEM_PRIVATE类型的块读取.但是当该块具有PAGE_GUARD保护时,我得到错误(函数返回0),为什么?
谢谢大家.
windows operating-system readprocessmemory virtualquery virtual-address-space
通过MPI传递函数指针作为告诉另一个节点调用函数的方法是否安全?有人可能会说通过MPI传递任何类型的指针都没有意义,但我写了一些代码来验证它.
//test.cpp
#include <cstdio>
#include <iostream>
#include <mpi.h>
#include <cstring>
using namespace std;
int f1(int a){return a + 1;}
int f2(int a){return a + 2;}
int f3(int a){return a + 3;}
using F=int (*)(int);
int main(int argc, char *argv[]){
MPI_Init(&argc, &argv);
int rank, size;
MPI_Status state;
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
//test
char data[10];
if( 0 == rank ){
*(reinterpret_cast<F*>(data))=&f2;
for(int i = 1 ; i < size ; ++i)
MPI_Send(data, 8, MPI_CHAR, i, 0, MPI_COMM_WORLD);
}else{
MPI_Recv(data, 8, MPI_CHAR, 0, …Run Code Online (Sandbox Code Playgroud) parallel-processing pointers mpi virtual-address-space c++11
首先我要承认,即使在阅读了一些相关资源之后,我对 Linux 上的高内存和低内存的概念仍然没有完全清楚。然而,根据我对 64 位 Linux 的了解,无论如何都没有高内存(如果我错了,请纠正我)。
我试图了解 kmap 和地址空间如何在defconfig为arm64配置的Linux内核版本5.8.1上工作。
我添加了以下系统调用:
SYSCALL_DEFINE1(mycall, unsigned long __user, user_addr)
{
struct page *pages[1];
int *p1, *p2;
p1 = (int *) user_addr;
*p1 = 1; /* this works */
pr_info("kernel: first: 0x%lx", (long unsigned) p1);
if (get_user_pages(user_addr, 1, FOLL_WRITE, pages, NULL) != 1)
return -1;
p2 = kmap(pages[0]);
*p2 = 2; /* this also works */
pr_info("kernel: second: 0x%lx", (long unsigned) p2);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我从用户空间分配整个内存页面(在页面边界上),并将其作为该系统调用的参数传递给内核。通过从内核内部取消引用任一指针来修改该内存效果非常好。但是,这两个指针具有不同的值:
[ 4.493480] kernel: first: 0x4ff3000
[ …Run Code Online (Sandbox Code Playgroud) memory-management linux-kernel virtual-address-space 32bit-64bit arm64
我的问题是关于处理地址空间的。
我有两个十六进制的地址空间:0x7fffff09和0x7fffff08。
我怎么知道它们是否可以被8或8字节对齐整除?就像检查在C或C ++代码中的样子一样。我知道您通常将mod用作常规数字,如果没有余数,那么就知道它是可整除的。
编辑:地址空间可以是__8,__ 16,__ 32(8位,16位,32位)
现在,如果我使用此代码尝试在GeForce GTX460SE(CC2.1)中使用CUDA5.5从CPU-Cores访问GPU-RAM,那么我会收到异常"访问冲突":
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <iostream>
int main()
{
unsigned char* gpu_ptr = NULL;
cudaMalloc((void **)&gpu_ptr, 1024*1024);
*gpu_ptr = 1;
int q; std::cin >> q;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但我们知道,有UVA(统一虚拟寻址).还有一些新的:
是否可以通过使用新CUDA6中的简单指针从CPU-Cores访问内存GPU-RAM?
我调试的GDB一个简单的程序,我看地址栈帧中的局部变量,看起来像下面- 0xffffbc10,0xffffc340等等.
这是我的理解是内核空间地址占用0xffffffff到0xcfffffff,并且该用户空间地址的开始0xbfffffff.
为什么这里出现差异?
编辑:请注意,我已关闭虚拟地址空间随机化,堆栈保护程序,并使用-m32编译.这是我的编译命令,如果它有帮助:
gcc -m32 -z execstack -fno-stack-protector -ggdb -static test.c -o test
这个问题纯粹出于好奇。我最近了解到,如果在Heap中动态分配内存空间,则删除内存空间非常重要。我的问题是,如果知道内存空间的地址,是否可以使用另一种C ++程序(从创建内存空间的程序)删除动态分配的内存空间?
这是一个例子:
代码01
#include <iostream>
using namespace std;
int main() {
int *a = new int;
cout << a;
int foo;
cin >> foo; // for blocking the program from closing.
return 0;
}
Run Code Online (Sandbox Code Playgroud)
CODE01.CPP的输出(例如)
0x7c1640
CODE02.CPP
#include <iostream>
using namespace std;
int main() {
int *a = (int*)0x7c1640;
delete a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这样行吗?如果我先运行code01.cpp,然后立即code02.cpp将堆中的内存删除了?
我潜伏在我的操作系统教科书中,它提到可以在数据断点上实现虚拟地址转换(用于程序调试)。我只知道调试器使用 INT 3 来暂停正在调试控制和地址寄存器中以某种方式处理的程序、局部和全局变量。但是经过一番挖掘,我只找到了有关使用调试寄存器的线性地址的信息。根本没有关于虚拟地址相关数据断点背后机制的文章或讨论。那么这究竟是如何工作的呢?
假设两个进程正在使用 Kernel32.dll,Windows 是否将 DLL 映射到两个进程中的同一虚拟地址空间?如果不是,分页机制最终如何使用实际上为两个进程加载 DLL 的相同物理地址?我尝试在 Windows 内部手册中查找此信息,但没有找到任何内容
在Linux上,是否可以让进程的线程在不同的虚拟地址空间上运行?如果是这样,怎么样?