【问题标题】:No error when using pointer after deleting the dynamically allocated memory it points at在删除它指向的动态分配的内存后使用指针时没有错误
【发布时间】:2015-08-29 15:26:09
【问题描述】:

我正在学习 C++ 中的动态内存。我的问题是为什么在以下代码中删除变量后我没有收到错误?

float* uf = new float(4.26);
delete uf;
cout << uf << '\n';
cout << *uf << '\n';

【问题讨论】:

  • 因为它是未定义的行为,而 UB 有时看起来工作得很好,但实际上并非如此。
  • 删除后取消引用指针会触发未定义的行为。未定义的行为可能会被忽视、触发分段错误或产生奇怪的输出......这就是程序员花这么多时间调试代码的原因!
  • 是的,我得到的不是 4.26,而是一个奇怪的数字,就像我做的一样 "float a; cout
  • 这个奇怪的数字来自进程专用的内存空间中的某个内存块。 Omho 在这种情况下,最好的结果是您的应用程序崩溃(由于分段错误),否则您可能会完全错过它,例如,当应用程序编译正常时,您可能会花费数小时试图弄清楚为什么会得到这个和那个结果算法方面你看不到任何问题。处理指针时的一种常见做法是在释放指针变量指向的内存后立即将其设置为 NULL,从而使指针变量无效。
  • 顺便说一句,我不明白为什么这个问题被否决了。这是一个合法的问题,除了它的表述方式(我已经编辑了一点)之外它很好。

标签: c++ pointers memory dynamic allocation


【解决方案1】:

你的意思是因为即使它显然是错误的,它也能编译?

可以说,在这种情况下,如果编译器真的愿意,它可能会产生警告,但这是一种简化的、不切实际的情况。

考虑以下示例:

float* uf = new float(4.26);
delete uf;
if (random_condition_known_only_at_runtime()) {
    uf = new float(0.0);
}
cout << uf << '\n';
cout << *uf << '\n';

或者:

float* uf = new float(4.26);
if (user_input == 'x') {
    delete uf;
}
cout << uf << '\n';
cout << *uf << '\n';

或者考虑并发;多个线程可以写入同一个指针。

关键是,实际代码通常会(直接或间接)在很大程度上依赖于 I/O 操作或其他类似的外部状态,因此无法在编译时提前知道指向的内存是否具有已经被删除了。


或者你的意思是因为程序没有崩溃?这是因为 C++ 标准没有规定崩溃。相反,它指的是“未定义的行为”,这意味着任何事情都可能发生,包括随机崩溃或根本没有影响。尝试访问已被删除的内存是这种未定义行为的典型示例。

【讨论】:

  • 虽然由于问题的性质(类别:C/C++ 编程新手)涉及多线程的概念是完全没有必要和阻碍的。
  • @rbaleksandar:没有“C/C++ 编程”。无论如何,问题不在于C。刚接触 C++ 并不意味着有人以前从未接触过多线程。
  • 好吧,我提到的 C/C++ 部分是不必要的,但这不会改变问题的本质。 “并不意味着有人以前从未接触过多线程” 是的,但假设在这里发布问题的每个人都有,那就更糟了。
  • @rbaleksandar:那么,为什么暗示多线程的存在是不好的(因为 C++11 也正式成为该语言的一部分)?这显然是一个“记住这样的事情存在,即使你现在深入挖掘还为时过早”的案例。
  • 它增加了另一层在这里不需要的复杂性(即使是“记住......”之类的东西)。
【解决方案2】:

编译时不会出现错误,因为当编译器尝试检测直接错误时,它不可能知道,在任何给定时间,天气或指针是否指向内存是否有效。

运行时您可能不会遇到错误,因为即使内存已“释放”,它仍然是内存。只是不能保证它不再是你的了。这是未定义行为的问题:它是未定义的;你永远不知道问题是如何表现出来的。

【讨论】:

    猜你喜欢
    • 2021-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    • 2016-03-02
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    相关资源
    最近更新 更多