C++Primer_第12章_动态内存

本文介绍C++中动态内存管理的基础知识,包括使用malloc分配内存的方法,并重点探讨了智能指针如shared_ptr、unique_ptr和weak_ptr的概念及其应用场景。通过实例对比了传统指针与智能指针在内存管理上的优劣。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先回顾一下C语言malloc函数,关于malloc的一个简单示例:

#include<stdio.h>  
#include<malloc.h>  
int main()  
{  
    char *p;  
   
    p=(char *)malloc(100);  
    if(p)  
        printf("Memory Allocated at: %x/n",p);  
    else  
        printf("Not Enough Memory!/n");  
    free(p);  
    return 0;  
}

一、动态内存与智能指针

shared_ptr允许多个指针指向同一个对象;

unique_ptr则独占所指向的对象;

weak_ptr弱引用,指向shared_ptr所管理的对象,

这三种类型都包含在#include<memory>.

二、shared_ptr

shared_ptr<string> p1; // shared_ptr that can point at a string
shared_ptr<list<int>> p2; // shared_ptr that can point at a list of ints

      p    将p用作一个条件判断,p指向一个对象则为true.

      *p  解引用p,获得它指向的对象

// if p1 is not null, check whether it's the empty string
if (p1 && p1->empty())
*p1 = "hi"; // if so, dereference p1 to assign a new value to that string

      最安全的分配和使用动态内存的方法是调用一个名为make_shared的标准库函数,

      此函数分配一个对象并初始化它,返回指向此对象的shared_ptr

// shared_ptr that points to an int with value 42
shared_ptr<int> p3 = make_shared<int>(42);
// p4 points to a string with value 9999999999
shared_ptr<string> p4 = make_shared<string>(10, '9');

      简便起见或者用auto,

// p6 points to a dynamically allocated, empty vector<string>
auto p6 = make_shared<vector<string>>();

      当进行拷贝或赋值操作时,每个shared_ptr都会记录有多少个其他shared_ptr指向相同的对象,可以认为有一个关联的计数器,引用计数reference count.

      shared_ptr的析构函数会递减它所指向的对象的引用计数,如果引用计数变为0,shared_ptr的析构函数就会销毁对象,并释放它所占用的内存。

void use_factory(T arg)
{
shared_ptr<Foo> p = factory(arg);
// use p
} // p goes out of scope; the memory to which p points is automatically freed//Because p is local to use_factory
shared_ptr<Foo> use_factory(T arg)
{
shared_ptr<Foo> p = factory(arg);
// use p
return p; // reference count is incremented when we return p
} // p goes out of scope; the memory to which p points is not freed
//In this version, the return statement in use_factory returns a copy of p 
//to its caller. Copying a shared_ptr adds to the reference count of that
//object.
      使用动态内存的一个常见原因是允许多个对象共享相同的状态。

三、直接管理内存

      delete表达式执行两个动作:销毁给定的指针指向的对象;释放对应的内存。

      使用newdelete管理动态内存三个常见问题:

      1.忘记delete内存,内存泄漏。

      2.使用已释放的对象。

      3.同一块内存释放两次。

坚持只使用智能指针,就可以避免所有这些问题。

      delete之后,指针虽然无效,但是指针仍有可能保存着地址,即空悬指针:

int *p(new int(42)); // p points to dynamic memory
auto q = p; // p and q point to the same memory
delete p; // invalidates both p and q
p = nullptr; // indicates that p is no longer bound to an object

      本例中,p和q指向相同的动态分配对象。delete此内存,然后将p置为nullptr,指出它不再指向任何对象。

      但是释放p指向的内存时,q也变为无效了!,在实际系统中,查找指向相同内存的所有指针是异常困难的。

四、范例应用

    使用内置指针:

/*
 Write a function that returns a dynamically allocated vector
of ints. Pass that vector to another function that reads the standard input
to give values to the elements. Pass the vector to another function to print
the values that were read. Remember to delete the vector at the
appropriate time.
*/

#include<iostream>
#include<vector>
#include<memory>
#include<string>
using std::vector;
using std::string;

//返回一个动态分配的int的vector
vector<int>*dynamic_vector_generator()
{
	vector<int>*ptr_v = new vector<int>();
	return ptr_v;
}

//将上面vector传递给另一个函数,并读取输入,存入vector
void dynamic_vector_processor(vector<int>*ptr_v)
{
	int i;
	std::cout << "plz enter:\n";
	while (std::cin >> i && i != 999)
		ptr_v->push_back(i);//(*ptr_v).push_back(i);
}

//传入另一个函数打印输入的vector
void dynamic_vector_printer(vector<int>* ptr_v)
{
	for (const auto &i : *ptr_v)
		std::cout << i << "  ";
	std::cout << "\n";
}
int main()
{
	vector<int>*ptr_vi = dynamic_vector_generator();
	dynamic_vector_processor(ptr_vi);
	dynamic_vector_printer(ptr_vi);

	delete ptr_vi;
	ptr_vi = nullptr;

	
	return 0;

}
    使用 shared_ptr的版本
shared_ptr<vector<int> >dynamic_vector_generator_sptr()
{
	return make_shared<vector<int>>();
}

void dynamic_vector_processor_sptr(shared_ptr<vector<int>> sptr_vi)
{
	int i;
	std::cout << "plz enter:\n";
	while (std::cin >> i && i != 999)
		sptr_vi->push_back(i);
}

void dynamic_vector_printer_sptr(const shared_ptr<vector<int>> sptr_vi)
{
	for (const auto& e : *sptr_vi)
		std::cout << e << ", ";
	std::cout << "\n";
}

int main()
{
	auto sptr = dynamic_vector_generator_sptr();
	dynamic_vector_processor_sptr(sptr);
	dynamic_vector_printer_sptr(sptr);

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luuyiran

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值