-1 c++ pointers memory-management
因此,当我了解指针时,我得到了一些疯狂的想法:如果我打印一个指针,它会给出内存中的一个地址,如果是这样,那么实际上读取了计算机内存的哪一部分?例如
#include <iostream>
using namespace std;
main()
{
int a=1;
int* ptr=&a;
int i=0;
while(1)
{
cout<<(ptr+i)<<"\t"<<*(ptr+i)<<"\n";
i++;
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行这个程序时(考虑到没有错误),它给了我来自&a++ 的地址。因此它循环访问内存中的地址,并显示存储在那里的信息。所以我的问题是,正在读取内存的哪一部分?我是否可以访问每个内存位置(每个内存位置中存储的值)?我可以通过这样的方式删除我的计算机上的文件(这听起来很愚蠢)吗
ptr=nullptr;
while(1)
{
*(ptr+i)=0;
i++;
}
Run Code Online (Sandbox Code Playgroud)
我不知道我的语法是否正确,尽管你明白了。我不敢在我的电脑上运行这个...
运行 C 或 C++ 程序时,地址可以分为以下几类:
那些已通过报告 const 限定对象地址的语言结构提供给 C 或 C++ 程序的对象。
那些已通过语言构造提供给 C 或 C++ 程序使用的对象,但不是从 const 限定对象派生的。
空地址。
环境已授予语言实现独占使用权,但尚未通过语言构造将其提供给程序使用。
那些语言实现一无所知的。
该标准没有对如果代码尝试对前三个类别之外的任何地址执行任何操作、尝试访问前两个类别之外的任何地址上的存储或尝试在不属于前两个类别的任何地址上写入存储的情况提出任何要求。第二类。
然而,设计为适合低级编程任务的实现将定义超出标准规定的行为。最值得注意的是,此类实现将“以环境的[记录的]时尚特征”处理类型#5的访问,无论环境记录它的时间和方式,其行为都将被记录。
例如,如果一个人正在运行一个针对 Commodore 64 的 C 实现,并且一个人执行*(char volatile*)0xD020 = 2;,这将导致屏幕边框变成红色,因为 Commodore 64 记录了写入该特定地址的效果。C 编译器对“屏幕”、“边框”或“红色”等概念一无所知,但它不需要知道这些东西。它只会执行对地址 0xD020 的写入,硬件将通过更改颜色控制锁存器中的值来响应,每当光栅扫描位于边界区域时,都会对这些锁存器进行采样。此类代码仅在定义将值 2 存储到地址 0xD020 的效果的平台上才有意义,但用于低级编程的实现不应期望知道,因此也不应关心此类构造何时会或将会没有用处,因为程序员通常比编译器编写者更了解目标环境。
顺便说一句,UB 可以擦除存储介质的想法可能与以下事实有关:在某些机器上,例如 Apple //c 或任何在插槽 6(通常位置)具有软盘控制器的 Apple Ii 系列机器上,访问(甚至当软盘驱动器运行时(包括软盘驱动器访问的第一秒左右的任何时间)读取)地址 0xC0EF 将导致驱动器开始覆盖当前磁道上的数据,直到下一次访问 0xC0EE。尽管大多数读取在大多数平台上不会产生副作用,但杂散读取可能产生灾难性后果的平台不仅仅是理论上的。