问题描述:
根据下列代码回答下列问题。
// Created by 黑马程序员.
#include "iostream"
using namespace std;
// 返回指针的函数,就在函数返回值声明和函数名之间添加*号即可
int * add(int a, int b)
{
int * sum = new int;
*sum = a + b;
return sum;
}
int main()
{
int * result1 = add(1, 2);
cout << *result1 << endl;
delete result1;
return 0;
}
D:\CLion_code\cmake-build-debug\CLion_code.exe
3
Process finished with exit code 0
问题:
函数的返回值可以是指针吗?可以的。函数返回指针的语法是什么呢?只需要在声明中,提供*,表示返回值是指针,然后在代码块中return指针。局部变量的定义是什么呢?局部变量是在函数内部创建的变量,其作用范围只在函数内部生效,函数执行完毕后,此变量销毁并所占内存空间释放。函数返回指针如何规避局部变量呢?局部变量是C+的静态内存管理,如果需要规避,需要动态内存管理(new和delete)。
问题解答:
在C++中,函数的返回值可以是指针。为了更好理解如何返回指针、如何规避局部变量以及动态内存管理的使用,以下将分点进行讲解。
1. 函数返回指针
函数可以返回指针,只需要在函数返回类型前加上 *
符号,表示返回一个指针。这样的函数允许我们将计算结果存储在指针所指向的内存地址中,然后返回这个指针。
示例代码中的函数 add
返回一个指向整数的指针:
int* add(int a, int b)
{
int * sum = new int; // 使用new动态分配内存
*sum = a + b; // 将a和b的和赋值给sum指针指向的内存
return sum; // 返回指针
}
2. 局部变量的定义
局部变量是指在函数内部声明的变量,它的生命周期仅限于该函数的执行过程。当函数结束时,局部变量的内存会自动被释放。
例如:
int* add(int a, int b)
{
int sum = a + b; // 这是局部变量 sum
return ∑ // 错误:返回局部变量的地址,函数结束后局部变量 sum 被销毁
}
上述代码是错误的,因为返回了局部变量的地址,当函数执行结束后,局部变量 sum
被销毁,返回的指针将指向已释放的内存,从而产生未定义行为。
3. 如何规避局部变量的生命周期问题
为了避免返回局部变量的指针引发问题,应该使用 动态内存分配(new
操作符)。new
在堆上分配内存,这些内存在手动释放之前不会被自动销毁,即使函数执行结束也仍然有效。
在示例代码中:
int* add(int a, int b)
{
int * sum = new int; // 动态分配内存
*sum = a + b; // 将计算结果存储在堆上
return sum; // 返回指针
}
通过 new
分配的内存不会在函数执行结束时销毁,因此可以安全地返回指针。调用 add
函数时,返回的指针 result1
指向在堆上分配的内存。
4. 动态内存管理
动态内存分配虽然解决了局部变量的生命周期问题,但必须记住在使用完动态分配的内存后,使用 delete
释放内存,否则会造成 内存泄漏。
在 main
函数中:
int* result1 = add(1, 2); // 调用add函数,返回指针
cout << *result1 << endl; // 输出结果
delete result1; // 释放动态分配的内存
delete result1
用于释放通过 new
分配的内存,避免内存泄漏。
总结
- 函数返回指针:在函数返回值类型中使用
*
表示返回指针。 - 局部变量的局限性:局部变量在函数结束后会被销毁,因此不能返回其地址。
- 动态内存分配:使用
new
动态分配内存可以避免局部变量生命周期的问题,但需要使用delete
来释放内存。