-1

如果指针数据类型与新输入的数据相同,我想它不会出错,但如果指针具有不同的数据类型,我们就会出现类型不匹配。我想知道编译器是否会对此做些什么(比如先删除悬空指针),或者只是给出一个错误。

4

3 回答 3

0

@YuHao 完全正确。

如果您是delete第一个,您可能会遇到分段错误,如果这会取消映射以前存在于您的进程地址空间中的页面。

在任何其他情况下,您只需在某处写入数据;当你这样做时,那里可能有有用的东西,可能没有。无论如何,您必须避免这种情况。

于 2015-08-26T17:19:56.597 回答
0

我想知道编译器是否会对此做些什么(比如先删除悬空指针)

可以(不会)

或者干脆给出一个错误。

可以(不会)

这是一个悬空指针。对此没有任何保护措施。

这是未定义的行为。这是根本无法回答的。

于 2015-08-26T17:24:31.960 回答
0

也许快速概述,以便我们在同一页面上会有所帮助。

让我们假设一台现代 PC 具有像 Linux 这样的多任务操作系统。

运行 C++ 程序时,会创建一个具有私有内存空间的进程。这是由 CPU 和操作系统转换为 RAM 中实际地址的地址的线性映射。

C++ 是一种具有手动内存管理的强类型低级语言。强类型意味着编译器会进行一些基本检查以确保程序中的逻辑语句有意义。指针只是另一种类型。

例如:

float f = 10.0f; // this is ok, 10.0f is a float literal
float* pF = &f;   // types match, & operator returns type float*
int i = f;        // types do not match. Compiler error or warning. 
int* i = pF;      // types do not match, int* is not float*
float f2 = pF;    // types do not match, float is not float*

等等。

那是编译时间。就是这样。一旦程序运行,C++ 运行时就非常愚蠢。它不会对内存操作进行太多检查,因为这些检查会减慢程序的速度,而 C++ 的理念是“如果您不要求,则无需为此付费”。

最基本的我们的记忆只是一个字节序列。float 和 int 等数据类型是多字节数据类型(32 位平台为 4 个字节)。这意味着内存中的浮点数存储在 4 个相邻字节大小的插槽中。

最后,我们准备回答您的问题。如果您在运行时通过诸如new返回指向您可以使用的内存的指针之类的方式分配内存。假设我们为单个浮点数执行此操作。new知道如何将该内存标记为“正在使用”。new不会将指向这 4 个字节的指针提供给其他任何人,因此您是安全的。当您调用delete它将内存返回给堆时 - 程序的其他部分可以稍后自由分配它。但是您拥有的指针未修改。我们仍然可以使用指针写入内存,只是现在我们遇到了麻烦。

例子:

float *pF = new float; // allocate 4-bytes on a 32-bit system
*pF = 10.0f;           // fine
delete pF;             // free the memory
*pF = 20.0f;           // ?????

最后一条指令说“将 20.0f 写入 pF 指向的内存”。我们不再“拥有”那段记忆。我们说这个指针是悬空的,因为它没有指向我们可以安全写入的有效内存。但它确实指向可写内存。你是对的,这是错误的来源。

有 C++ 内存分配器会将特殊值写入内存以指示它是未初始化还是先前已删除。这将取决于您的操作系统和工具集。

查找此类错误的另一个选择是使用很棒的工具Valgrind,它将模拟您的程序内存并标记这些类型的错误。

于 2015-08-26T17:53:12.797 回答