BGONE 2024-06-18 10:25 采纳率: 60%
浏览 1

C 中的函数和内存:在堆上分配内存

int* secondary_function(){
  int integer_var = 23;
  return &integer_var;}
int main(){
    int *integer_var_pointer = secondary_function();}

以上代码有什么问题?

  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-06-18 10:25
    关注

    引自免费微信小程序:皆我百晓生

    在提供的 C++ 代码示例中,存在的主要问题是局部变量的生命周期与返回引用之间的冲突。具体来说,在secondary_function函数中定义的integer_var是一个局部变量,其存储在栈上,当函数执行完毕后,这个局部变量就会被销毁。然而,函数返回的是指向这个局部变量的指针,这导致在main函数中获取的指针实际上指向了一个已经不存在的内存位置。

    这种行为被称为悬挂指针(dangling pointer),当尝试通过这个指针访问数据时,程序可能会表现出未定义行为,包括崩溃、随机结果或数据损坏。

    为了解决这个问题,可以考虑在堆上分配内存,因为堆上的内存直到显式地被释放前都是有效的。以下是修改后的代码示例:

    #include <iostream>
    
    int* secondary_function(){
      int *integer_var = new int(23); // 使用 new 在堆上分配内存,并初始化
      return integer_var;}
    
    int main(){
        int *integer_var_pointer = secondary_function();
        
        // 使用前检查指针是否非空
        if(integer_var_pointer != nullptr){
            std::cout << "Value: " << *integer_var_pointer << std::endl;
        }
        
        delete integer_var_pointer; // 记得释放堆上分配的内存
        return 0;
    }
    

    在这个版本中,secondary_function使用new操作符在堆上分配了内存,并将新创建的整数对象的地址返回给调用者。在main函数中,我们首先检查返回的指针是否有效,然后使用它并最终调用delete操作符来释放之前分配的内存,防止内存泄漏。

    值得注意的是,对于更复杂的资源管理,使用智能指针(如std::unique_ptrstd::shared_ptr)可以提供更好的安全性和自动内存管理,从而避免手动调用newdelete可能带来的错误。例如:

    #include <iostream>
    #include <memory>
    
    std::unique_ptr<int> secondary_function(){
      return std::make_unique<int>(23);}
    
    int main(){
        auto integer_var_pointer = secondary_function();
        
        std::cout << "Value: " << *integer_var_pointer << std::endl;
        
        return 0;
    }
    

    在这个例子中,std::unique_ptr会自动管理内存,当integer_var_pointer超出作用域时,它所持有的资源将被自动释放,无需手动调用delete

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 6月18日