cpp中include memory
时间: 2024-06-04 15:09:53 浏览: 7
在 C++ 中,头文件 `<memory>` 提供了智能指针和其他内存管理工具,是 C++ STL 的一部分。
其中最常用的是智能指针,可以用来管理动态分配的内存,避免内存泄漏和空指针错误。通过使用智能指针,程序员可以更加安全和方便地管理堆内存,避免手动调用 `new` 和 `delete` 导致的问题。
智能指针有三种类型:`unique_ptr`、`shared_ptr` 和 `weak_ptr`。其中 `unique_ptr` 是独占式的智能指针,只能有一个指向某个对象的 `unique_ptr`,当 `unique_ptr` 被销毁时,它所指向的对象也会被自动删除。`shared_ptr` 和 `weak_ptr` 则支持多个指针指向同一个对象,但 `shared_ptr` 会维护一个引用计数,当引用计数为0时才会自动删除对象,而 `weak_ptr` 不会增加引用计数,只是提供了一种非拥有式的访问方式。
此外,头文件 `<memory>` 还提供了一些其他的内存管理工具,如:`make_shared`、`make_unique`、`allocate_shared`、`allocate_unique` 等。这些函数可以更加方便地创建和管理动态分配的对象。
相关问题
ffmepg cpp dav转mp4
使用FFmpeg库可以将DAV文件转换为MP4格式。以下是C++代码示例:
```cpp
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
}
int main()
{
const char* input_filename = "input.dav";
const char* output_filename = "output.mp4";
AVFormatContext* input_format_context = nullptr;
AVFormatContext* output_format_context = nullptr;
AVCodec* codec = nullptr;
AVCodecContext* codec_context = nullptr;
AVStream* stream = nullptr;
AVPacket packet;
AVFrame* frame = nullptr;
SwsContext* sws_context = nullptr;
uint8_t* buffer = nullptr;
int video_stream_index = -1;
int ret = 0;
// Open input file
ret = avformat_open_input(&input_format_context, input_filename, nullptr, nullptr);
if (ret < 0)
{
printf("Error opening input file\n");
return -1;
}
// Get stream information
ret = avformat_find_stream_info(input_format_context, nullptr);
if (ret < 0)
{
printf("Error getting stream information\n");
return -1;
}
// Find video stream
for (unsigned int i = 0; i < input_format_context->nb_streams; i++)
{
if (input_format_context->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
{
video_stream_index = i;
break;
}
}
if (video_stream_index == -1)
{
printf("Error finding video stream\n");
return -1;
}
// Open codec
codec = avcodec_find_decoder(input_format_context->streams[video_stream_index]->codecpar->codec_id);
if (!codec)
{
printf("Error finding decoder\n");
return -1;
}
codec_context = avcodec_alloc_context3(codec);
if (!codec_context)
{
printf("Error allocating codec context\n");
return -1;
}
ret = avcodec_parameters_to_context(codec_context, input_format_context->streams[video_stream_index]->codecpar);
if (ret < 0)
{
printf("Error setting codec parameters\n");
return -1;
}
ret = avcodec_open2(codec_context, codec, nullptr);
if (ret < 0)
{
printf("Error opening codec\n");
return -1;
}
// Open output file
avformat_alloc_output_context2(&output_format_context, nullptr, nullptr, output_filename);
if (!output_format_context)
{
printf("Error allocating output context\n");
return -1;
}
codec = avcodec_find_encoder(AV_CODEC_ID_H264);
if (!codec)
{
printf("Error finding encoder\n");
return -1;
}
stream = avformat_new_stream(output_format_context, codec);
if (!stream)
{
printf("Error creating new stream\n");
return -1;
}
codec_context = avcodec_alloc_context3(codec);
if (!codec_context)
{
printf("Error allocating codec context\n");
return -1;
}
codec_context->codec_id = codec->id;
codec_context->codec_type = AVMEDIA_TYPE_VIDEO;
codec_context->width = input_format_context->streams[video_stream_index]->codecpar->width;
codec_context->height = input_format_context->streams[video_stream_index]->codecpar->height;
codec_context->time_base = input_format_context->streams[video_stream_index]->time_base;
codec_context->pix_fmt = AV_PIX_FMT_YUV420P;
ret = avcodec_parameters_from_context(stream->codecpar, codec_context);
if (ret < 0)
{
printf("Error setting codec parameters\n");
return -1;
}
ret = avcodec_open2(codec_context, codec, nullptr);
if (ret < 0)
{
printf("Error opening codec\n");
return -1;
}
ret = avio_open(&output_format_context->pb, output_filename, AVIO_FLAG_WRITE);
if (ret < 0)
{
printf("Error opening output file\n");
return -1;
}
ret = avformat_write_header(output_format_context, nullptr);
if (ret < 0)
{
printf("Error writing header\n");
return -1;
}
// Allocate frame and buffer
frame = av_frame_alloc();
if (!frame)
{
printf("Error allocating frame\n");
return -1;
}
int buffer_size = av_image_get_buffer_size(codec_context->pix_fmt, codec_context->width, codec_context->height, 1);
buffer = (uint8_t*)av_malloc(buffer_size * sizeof(uint8_t));
av_image_fill_arrays(frame->data, frame->linesize, buffer, codec_context->pix_fmt, codec_context->width, codec_context->height, 1);
sws_context = sws_getContext(input_format_context->streams[video_stream_index]->codecpar->width, input_format_context->streams[video_stream_index]->codecpar->height, input_format_context->streams[video_stream_index]->codecpar->format, codec_context->width, codec_context->height, codec_context->pix_fmt, SWS_BICUBIC, nullptr, nullptr, nullptr);
// Read frames and write to output file
while (av_read_frame(input_format_context, &packet) >= 0)
{
if (packet.stream_index == video_stream_index)
{
ret = avcodec_send_packet(codec_context, &packet);
if (ret < 0)
{
printf("Error sending packet to decoder\n");
return -1;
}
while (ret >= 0)
{
ret = avcodec_receive_frame(codec_context, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
else if (ret < 0)
{
printf("Error receiving frame from decoder\n");
return -1;
}
sws_scale(sws_context, frame->data, frame->linesize, 0, input_format_context->streams[video_stream_index]->codecpar->height, frame->data, frame->linesize);
frame->pts = av_rescale_q(frame->pts, input_format_context->streams[video_stream_index]->time_base, stream->time_base);
frame->pkt_dts = av_rescale_q(frame->pkt_dts, input_format_context->streams[video_stream_index]->time_base, stream->time_base);
frame->pkt_duration = av_rescale_q(frame->pkt_duration, input_format_context->streams[video_stream_index]->time_base, stream->time_base);
frame->pkt_pos = -1;
ret = avcodec_send_frame(codec_context, frame);
if (ret < 0)
{
printf("Error sending frame to encoder\n");
return -1;
}
while (ret >= 0)
{
ret = avcodec_receive_packet(codec_context, &packet);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
else if (ret < 0)
{
printf("Error receiving packet from encoder\n");
return -1;
}
packet.stream_index = stream->index;
packet.pts = av_rescale_q(packet.pts, codec_context->time_base, stream->time_base);
packet.dts = av_rescale_q(packet.dts, codec_context->time_base, stream->time_base);
packet.duration = av_rescale_q(packet.duration, codec_context->time_base, stream->time_base);
packet.pos = -1;
ret = av_interleaved_write_frame(output_format_context, &packet);
if (ret < 0)
{
printf("Error writing packet\n");
return -1;
}
av_packet_unref(&packet);
}
}
}
av_packet_unref(&packet);
}
// Flush encoder
ret = avcodec_send_frame(codec_context, nullptr);
if (ret < 0)
{
printf("Error flushing encoder\n");
return -1;
}
while (ret >= 0)
{
ret = avcodec_receive_packet(codec_context, &packet);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
else if (ret < 0)
{
printf("Error receiving packet from encoder\n");
return -1;
}
packet.stream_index = stream->index;
packet.pts = av_rescale_q(packet.pts, codec_context->time_base, stream->time_base);
packet.dts = av_rescale_q(packet.dts, codec_context->time_base, stream->time_base);
packet.duration = av_rescale_q(packet.duration, codec_context->time_base, stream->time_base);
packet.pos = -1;
ret = av_interleaved_write_frame(output_format_context, &packet);
if (ret < 0)
{
printf("Error writing packet\n");
return -1;
}
av_packet_unref(&packet);
}
av_write_trailer(output_format_context);
// Free memory
if (input_format_context)
avformat_close_input(&input_format_context);
if (output_format_context)
{
if (output_format_context->pb)
avio_closep(&output_format_context->pb);
avformat_free_context(output_format_context);
}
if (codec_context)
avcodec_free_context(&codec_context);
if (frame)
av_frame_free(&frame);
if (buffer)
av_free(buffer);
if (sws_context)
sws_freeContext(sws_context);
return 0;
}
```
上述代码使用了FFmpeg库中的许多功能,例如打开文件、解码视频、编码视频、写入文件等。如果您不熟悉FFmpeg,建议先了解一些基本的概念和用法。
C++中make_shared
在C++中,make_shared是一个函数模板,用于创建一个shared_ptr智能指针对象。它可以方便地将动态分配的内存与智能指针绑定在一起,从而实现自动内存管理。
make_shared函数模板的语法如下:
```cpp
template <typename T, typename... Args>
shared_ptr<T> make_shared(Args&&... args);
```
其中,T是指向对象的类型,Args是构造函数的参数类型。
使用make_shared函数可以更简洁地创建shared_ptr对象,而不需要显式地使用new操作符。它会自动分配内存并调用对象的构造函数来初始化。
下面是一个使用make_shared函数创建shared_ptr对象的示例:
```cpp
#include <memory>
class MyClass {
public:
MyClass(int value) : m_value(value) {
std::cout << "Constructor called" << std::endl;
}
~MyClass() {
std::cout << "Destructor called" << std::endl;
}
private:
int m_value;
};
int main() {
auto ptr = std::make_shared<MyClass>(10);
// 使用ptr指向的对象
return 0;
}
```
在上面的示例中,make_shared函数创建了一个shared_ptr对象ptr,并将其指向一个MyClass对象。当ptr超出作用域时,智能指针会自动释放内存,并调用MyClass对象的析构函数。