C++ 如何在内存位置声明指针并使用值初始化它

C++ 如何在内存位置声明指针并使用值初始化它,c++,pointers,C++,Pointers,当我运行这段代码时,我得到了一个分段错误,我理解为什么我会得到它,因为我没有使用新的初始值设定项为它分配空间。我该如何做我想做的事?通过查看我的代码,您应该能够看到我在做什么,但万一您不能告诉我。我试图声明一个指向特定地址的指针,然后向该地址传递一个值。这是我的密码: #include <iostream> using namespace std; int main(){ double *ptr; ptr= (double*) 0x7fff07814c28;

当我运行这段代码时,我得到了一个分段错误,我理解为什么我会得到它,因为我没有使用新的初始值设定项为它分配空间。我该如何做我想做的事?通过查看我的代码,您应该能够看到我在做什么,但万一您不能告诉我。我试图声明一个指向特定地址的指针,然后向该地址传递一个值。这是我的密码:

#include <iostream>
using namespace std;

int main(){


    double *ptr;
    ptr= (double*) 0x7fff07814c28;
    *ptr= 77.9;
    cout<< "pointer value \n";
    cout<< ptr;
    cout<< "\n";
    cout<< "value pointed to by pointer \n";
    cout<< *ptr;
    cout<< "\n";

    }
#包括
使用名称空间std;
int main(){
双*ptr;
ptr=(双*)0x7fff07814c28;
*ptr=77.9;
库特
这没有任何意义。在现代操作系统中,内存操作不是实模式,因此无法直接寻址

内存不是一个C数组(例如,如果您有4GB,就不能用
无符号长m[0]
来寻址第一个字节)

内存由CPU以各种模式管理(受保护,标准为long),因此,您无法知道“精确”阵列位置

简而言之,使用
new[]
,或者更好的STL

如何解释指针

您可以像这样声明一个指针(指向
double
):

double* ptr;
…在内存位置

您可以使用内存位置初始化指针:

double* ptr = some_address;
或在声明后分配:

ptr = some_another_address;
并使用一个值初始化它

有几种方法可以获取对象的存储:

  • 您可以通过定义变量来获取静态、线程静态和本地存储。例如,指针变量
    ptr
    的存储是这样分配的-不要与指针指向的存储混淆
  • 您可以使用(n)分配
    new
    表达式(或C标准库中的
    std::malloc
    函数族)获取动态存储

两个选项都不允许指定存储地址的内存地址。标准C++中没有办法从任意地址请求变量的存储。


当我运行这段代码时,我得到了一个分段错误

从C++的角度来看,原因是:您通过一个不指向对象的指针进行间接操作。程序的行为是未定义的

从操作系统的角度来看,原因是:进程试图写入未映射或标记为受保护或只读的虚拟地址,因此操作系统发出信号并终止进程


现在,如果<强>并且仅当< /强>您使用的C++实现为您提供了任意的内存位置可以用于存储的保证,那么您可以使用放置新表达式来创建该内存位置中的对象。这种情况的示例是“代码> MMAP在POSIX系统上调用。这里是一个如何使用CRE的例子。在这样的存储器中读取对象:

// let there be storage at some memory address
// let the amount of storage, and alignment of the address be sufficient for T
char* storage = some_special_address;

// create an object into the storage
T* tptr = new(storage) T;

// after you're done using the object, destroy it:
tptr->~T();
// after destruction, the storage can be released, if needed and if possible
我该如何做我想做的事


在不使用虚拟内存的系统上运行程序(即,在没有操作系统的系统上)。然后查阅该系统的手册,了解您可以使用哪些内存地址。然后查看上一个示例,了解如何在您控制的存储器中创建对象。确保该地址满足您创建的对象的对齐要求。

访问内存空间中的特定地址取决于平台和操作系统

在许多桌面系统(如Windows和Linux)上,操作系统授予您的程序访问部分内存的权限。任何超出这些限制的访问都将导致分段错误或其他错误。如果该地址范围内有内存,您必须拥有访问内存中特定区域的内核权限

在嵌入式系统上,指针被分配到特定的地址,以访问内存和硬件设备。这还取决于操作系统(如果有)是否授予您访问这些设备的权限。此外,当您访问未定义的地址或与这些地址无关的地址时,请做好未定义行为的准备。(在许多嵌入式系统中,寻址空间被解码用于各种用途,如USB控制器。如果地址不被解码,未定义的行为就会出现。)

在访问随机位置之前,请验证是否存在某个位置,以及您是否有访问该位置的权限


搜索“操作系统虚拟内存”。

指针与动态内存正交。你从哪里找到代码?0x7FFF07814C28;< /Cord>从实际中获得?布瑞恩,不要读任何教程。读一本好的C++书:而不是“我怎么做我想做的事”?你应该问“为什么我要这样做?”任何虚拟地址操作系统中的地址都是进程特定的。一个进程(或内核)中的地址与不同进程中的同一地址无关。这一行实际上起作用了这一行:*ptr=77.9;这不起作用你的第一句话是不正确的。它确实有意义,尽管在这一点上,ptr
不是安全派生的指针,但它们有很多用途,尤其是嵌入式系统。总的来说,我认为不是他的答案过于简单,不太可能对OP有所帮助。使用
new[]
的最后一条建议似乎大错特错,提到STL是完全没有根据的。我指的是无意义的代码,而不是真正崩溃的代码:)我想说的是,如果我注释掉与指针指向的值有关的行,我可以初始化指向该地址的指针,但此时无法更改该值it@BrianKreidberg“但是你想做什么呢?”亚历山大·张:是的。
// let there be storage at some memory address
// let the amount of storage, and alignment of the address be sufficient for T
char* storage = some_special_address;

// create an object into the storage
T* tptr = new(storage) T;

// after you're done using the object, destroy it:
tptr->~T();
// after destruction, the storage can be released, if needed and if possible