一、前言

  前面两篇已经编写了内存配置器和建构解构工具函数。这里,就准备编写并介绍下内存基本处理工具函数。比如uninitialized_copy()、uninitialized_copy和 uninitialized_copy_n()等的实现。

二、内存工具函数简介

1.uninitialized_copy函数

  uninitialized_copy()使我们能够将内存的配置与对象的建构行为分离开来。如果作为输出目的地的[result, result+(last-first))范围内的每一个迭代器都指向未初始化区域,则uninitialized_copy()会使用copy construct,为身为输入来源[first, last)范围内的每一个对象产生一份复制品,放进输出范围中。

  如果你需要初始化一个容器的话,这个函数可以其很大最用。通过用两步完成:配置内存区块;然后使用uninitizlied_copy,在该内存区块上建构元素。

  c++标准还规定uninitialized_copy()具有"commit or rollback"语意。即,要么建构出所有元素,要么不建构任何东西,不能存在半建构状态。

  下面是uninitialized_copy函数调用结构图:

图1:uninitialized_copy函数体系

  uninitialized_copy()是一个模版函数:

 // uninitialized_copy 的函数模板
// uninitialized_copy -> __uninitialized_copy
// 利用编译器的类型推导,萃取处迭代器指向的类型
// 以便最后通过类型萃取__type_traits机制获取迭代器指向类型的一些属性
template <class InputIterator, class ForwardIterator>
inline ForwardIterator
uninitialized_copy(InputIterator first, InputIterator last,
ForwardIterator result)
{
// value_type是个模板函数,萃取迭代器指向类型,用该类型生成临时对象,
// 再利用类型推导
return __uninitialized_copy(first, last, result, value_type(result)); }

  在uninitialized_copy()内调用了一个内部的实现函数__uninitialized_copy(),这个调用的目的就是为了利用编译器的类型推导功能,获取迭代器的指向对象的类型。下面是内部调用的__unintialized_copy()函数:

 // __uninitialized_copy-->__uninitilaized_copy_aux
// 是为利用编译器的类型参数推导,判断是否是POD类型
template <class InputIterator, class ForwardIterator, class T>
inline ForwardIterator
__uninitialized_copy(InputItearator first, InputIeratorlast,
ForwardIterator result, T*)
{
// is_POD 是一种类型,或者是__true_type代表为真,__
// false_type代表为否,假
// 利用is_POD的不同定义,生成不同的临时对象,用其进行重载
typedef typename __type_traits<T>::is_POD_type is_POD;
return __uninitialized_copy_aux(first, last, result, is_POD());
}

  在__uninitialized_copy()内部又利用了类型属性萃取类型萃取了迭代器指向对象类型是否是POD,并利用is_POD生成对象用于重载。对于__uninitialized_copy_aux(),源码如下:

a. is_POD定义为__true_type

// 如果是POD型别,那么copy construction 等同于 assignment,而且
// destruction 是trivial,以下就有效
// 执行流程就会转进到以下函数。
// POD 意指Plain Old Data,指标量型别或者是传统的C Struct型别
// POD型别必须拥有trivial ctor/dtor/copy/assignment函数
// 这是藉由function template的参数推导机制而得
template <class InputIterator, class ForwardIterator>
inline ForwardIterator
__uninitialized_copy_aux(InputIterator first, InputIterator last,
ForwardIterator result,
__true_type)
{
//这里的_true_type 代表迭代器指向的类型是POD型别,不用构造,可以
//直接拷贝
return copy(first, last, result);
}

b.is_POD定义为__false_type

  不是POD类型,那么对于每一个元素,都需要调用其copy construct函数进行构造

 template <class InputIterator, class ForwardIterator>
ForwardIerator
__uninitialized_copy_aux(InputIterator first, InputIterator last,
ForwardIterator result,
__false_type)
{
//这里的_false_type 代表迭代器指向的类型非POD型别,
//不能直接拷贝,需要一个一个的调用其构造函数
ForwardIterator cur = result;
__STL_TRY
{
for (; first != last; ++first, ++cur)
construct(&*cur, *first);
return cur;
}
//commit or rollback
__STL_UNWIND(destroy(result, cur));
}

c.针对char*和wchar_t* 的特化版本

  对于char*类型的迭代器,其迭代器指向的对象类型是char,对于char利用内存底层的memmove()复制速度更快。所以针对char*编写出其的特化版本。上述理由对于wchar_t*也是成立。源码如下:

 // uninitialized_copy 对于char* 的特化版本
inline char* uninitialized_cpoy(const char* first, const char* last,
char* result)
{
//对于char *对其使用memmove效率最高
memmove(result, first, last - first);
return result + (last - first);
}
 // unitialized_copy 对于 wchar_t* 的特化版本
inline wchar_t* uninitialized_copy(const wchar_t* first,
const wchar_t* last, wchar_t* result)
{
//同样对于wchar_t *对其使用memmove效率最高
memmove(result, first, sizeof(wchar_t) * (last - first));
return result + (last - first);
}

2.uninitialized_copy_n函数

  该函数调用接口为uninitialized_copy_n(InputIterator first, Size count,ForwardIterator result),这个函数接受一个输入迭代器,和输出迭代器,以及要复制的个数。

  函数对外的接口实现:

 template <class InputIterator, class Size, class ForwardIterator>
inline pair<InputIterator, ForwardIterator>
uninitialized_copy_n(InputIterator first, Size count,
ForwardIterator result)
{
// 利用模板函数iterator_category提取出first迭代器的分类型别
// 然后利用其型别进行重载,对于不同的型别进行不同的优化处理
return __uninitialized_copy_n(first, count, result,
iterator_category(first));
}

  利用迭代器的分类类型产生临时对象,并利用其进行重载,对不同的分类类型进行不同的适当处理.

a.迭代器分类为random_ierator_tag

 template <class RandomAccessItearator, class Size, class ForwardIterator>
inline pair<RandomAccessIterator, ForwardIterator>
__uninitialized_copy_n(RandomAccessIterator first, Size count,
ForwardIterator result, random_ierator_tag)
{
// 对于random_iterator_tag类型的迭代器
// 可以利用first和count计算出last迭代器
// 然后利用uninitialized_copy(first, last, result)
// 然而对于input_iterator_tag,就不能
RandomAccessIterator last = first _count;
return make_pair(last, uninitialized_copy(first, last, result));
}

b.迭代器分类为输入迭代器,前向迭代器和双向迭代器时

  由于迭代器的分类标签类型的继承关系,

 //五个作为标记用的型别(tag types)
struct input_iterator_tag { };
struct forward_iterator_tag : public input_iterator_tag { };
struct bidirectional_iterator_tag : public forward_iterator_tag { };
struct random_access_iterator_tag : public bidirectional_iterator_tag { };

后面三种迭代器类型,都会进行隐式类型转换,转换为input_ierator_tag。

 // input_iterator_tag 是迭代器的分类中的一种,利用迭代器分类类型的不同
// 可以进行重载,不同的迭代器的类型,会针对其有特定的最优实现
template <class InputItearator, class Size, class ForwardIterator>
pair<InputIterator, ForwardIterator>
__uninitialized_copy_n(InputIterator first, Size count,
ForwardIterator result, input_ierator_tag)
{
// 对于input_iterator_tag类型的迭代器,只能逐个调用构造
ForwardIterator cur = result;
__STL_TRY
{
for (; count > ; --count, ++first, ++cur)
construct(&*cur, *first);
return pair<InputIterator, ForwardIterator>(first, cur);
}
// commit or rollback
__STL_UNWIND(destroy(result, cur));
}

3.uninitialized_fill函数

  uninitialized_fill()也能够使我们将内存配置与对象的建构行为分离开。如果[first, last)范围内每个迭代器都指向未初始化的内存,那么uninitialized_fill()会在该范围内产生x的复制品。全部初始化为x。与uninitialized_copy()不同,uninitialized_copy()是以一段迭代器标记的区块内的元素去初始化自己的未初始化元素。这里是全部初始化为同一个指定的值x。下面是uninitialized_fill()函数的实现体系:

图2:uninitialized_fill()函数的实现体系

  下面,先是uninitialized_fill函数对外的接口的实现:

 // uninitialized_fill()对外接口
template <class ForwardIterator, class T>
inline void uninitialized_fill(ForwardIterator first, ForwardIterator last,
const T& x)
{
__uninitialized_fill(first, last, x, value_type(first));
}

  在这里uninitialized_fill()----->__uninitialized_fill()的调用还是为了利用编译器的类型推导功能,获取迭代器指向对象的类型。

 // 内部的第二层,用于提取迭代器指向的类型是否是POD类型
// 并利用其进行重载
template <class ForwardIterator, class T, class T1>
inline void __uninitialized_fill(ForwardIterator first,
ForwardIterator last, const T& x, T1*)
{
// 利用__type_traits来萃取is_POD_type定义的类型
// 并利用其调用更底层的重载实现
typedef typename __type_traits<T1>::is_POD_type is_POD;
__uninitialized_fill_aux(first, last, x, is_POD());
}

  在__uninitialized_fill()中,我们依旧是利用类型属性萃取类型,萃取了迭代器指向对象类型的属性,获取其is_POD类型的定义,并利用其定义产生临时对象,进行重载,对于不同的情况,进行不同的适当处理。

a.is_POD类型定义为__true_type

 // 如果是POD型别,那么copy construction 等同于 assignment,而且
// destructor 是trivial,以下就有效
// 执行流程就会转进到以下函数。
template <class ForwardIterator, class T>
inline void
__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last,
const T& x, __true_type)
{
// isPOD的类型定义为__true_type,表示是POD类型
fill(first, last, x); //调用STL算法fill()
}

b.is_POD类型定义为__false_type

 template <class ForwardIterator, class T>
void
__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last,
const T& x, __false_type)
{
// is_POD定义为__false_type表示不是POD类型,所以只能逐个构造
ForwardIterator cur = first;
__STL_TRY
{
for (; cur != last; ++cur)
construct(&*cur, x);
}
// commit or rollback
__STL_UNWIND(destroy(first, cur));
}

4.uninitialized_fill_n函数

  uninitialized_fill_n()也能够使我们将内存配置与对象的建构行为分离开。uninitialized_fill_n(ForwardIterator first,Size n,const T& x),这个函数接受一个前向迭代器,一个指定的初始化初值,和要初始化的个数。基本原理于uninitialized_copy_n一样。uninitialized_fill_n()实现的体系如下:

图3:uninitialized_fill_n()实现的体系

  

  源码如下:

 // uninitialized_fill_n的实现

 // 基本原理于uninitialized_copy_n一样

 template <class ForwardIterator, class Size, class T>
inline ForwardIterator
__uninitialized_fill_n_aux(ForwardIterator first, Size n,
const T& x, __true_type)
{
return fill_n(first, n, x);
} template <class ForwardIterator, class Size, class T>
ForwardIterator
__uninitialized_fill_n_aux(ForwardIterator first, Size n,
const T& x, __false_type)
{
ForwardIterator cur = first;
__STL_TRY
{
for (; n > ; --n, ++cur)
construct(&*cur, x);
return cur;
}
__STL_UNWIND(destroy(first, cur));
} template <class ForwardIterator, class Size, class T, class T1>
inline ForwardIterator __uninitialized_fill_n(ForwardIterator first,
Size n, const T& x, T1*)
{
typedef typename __type_traits<T1>::is_POD_type is_POD;
return __uninitialized_fill_n_aux(first, n, x, is_POD());
} // uninitialized_fill_n对外接口
template <class ForwardIterator, class Size, class T>
inline ForwardIterator uninitialized_fill_n(ForwardIterator first,Size n,
const T& x)
{
return __uninitialized_fill_n(first, n, value_type(first));
}

5.__uninitialized_copy_copy、__uninitialized_fill_copy和__uninitialized_copy_fill函数

  这几个函数比较简单,都是调用上面的函数就可以实现功能了,就不解释了。直接上源码:

 // 拷贝[first1, last1)到[result, result + (last1 - first1))
// 同时拷贝[first2, last2)到
// [result + (last1 - first1), result + (last1 - first1) + (last2 - first2)] template <class InputIterator1, class InputIterator2, class ForwardIterator>
inline ForwardIterator
__uninitialized_copy_copy(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator last2, ForwardIterator result)
{
ForwardIterator mid = uninitialized_copy(first1, last1, reuslt);
__STL_TRY
{
return uninitialized_copy(first2, last2, mid);
}
__STL_UNWIND(destroy(result, mid));
} // 用x填充[result, mid),同时拷贝[first, last)到[mid, mid + (last - first))
template <class ForwardIterator, class T, class InputIterator>
inline ForwardIterator
__uninitialized_fill_copy(ForwardIterator result, ForwardIterator mid,
const T& x, InputIterator first, InputIterator last)
{
uninitialized_fill(result, mid, x);
__STL_TRY
{
return uninitialized_copy(first, last, mid);
}
__STL_UNWIND(destroy(result, mid));
} // 拷贝[first1, last1)到[first2, first2 + (last1 - first1))
// 并且用x填充[first2 + (last1 - first1), last2]
template <class InputIterator, class ForwardIterator, class T>
inline void
__uninitialized_copy_fill(InputIterator first1, InputIterator last1,
ForwardIterator first2, ForwardIterator last2,
const T& x)
{
ForwardIterator mid2 = uninitialized_copy(first1, last1, first2);
__STL_TRY
{
uninitialized_fill(mid2, last2, x);
}
__STL_UNWIND(destroy(first2, mid2));
}

三、完整源码stl_uninitialized_wjzh.h

 /*************************************************************************
> File Name: stl_uninitialized_wjzh.h
> Author: wjzh
> Mail: wangjzh_1@163.com
> Created Time: 2014年11月04日 星期二 17时09分15秒
************************************************************************/ // 该文件中提供五个全局函数,作用于未初始化空间上 #ifndef __SGI_STL_INTERNAL_UNINITIALIZED_WJZH_H
#define __SGI_STL_INTERNAL_UNINITIALIZED_WJZH_H __STL_BEGIN_NAMESPACE // uninitialized_copy的实现 // 如果是POD型别,那么copy construction 等同于 assignment,而且
// destruction 是trivial,以下就有效
// 执行流程就会转进到以下函数。
// POD 意指Plain Old Data,指标量型别或者是传统的C Struct型别
// POD型别必须拥有trivial ctor/dtor/copy/assignment函数
// 这是藉由function template的参数推导机制而得
template <class InputIterator, class ForwardIterator>
inline ForwardIterator
__uninitialized_copy_aux(InputIterator first, InputIterator last,
ForwardIterator result,
__true_type)
{
//这里的_true_type 代表迭代器指向的类型是POD型别,不用构造,可以
//直接拷贝
return copy(first, last, result);
} template <class InputIterator, class ForwardIterator>
ForwardIerator
__uninitialized_copy_aux(InputIterator first, InputIterator last,
ForwardIterator result,
__false_type)
{
//这里的_false_type 代表迭代器指向的类型非POD型别,
//不能直接拷贝,需要一个一个的调用其构造函数
ForwardIterator cur = result;
__STL_TRY
{
for (; first != last; ++first, ++cur)
construct(&*cur, *first);
return cur;
}
//commit or rollback
__STL_UNWIND(destroy(result, cur));
} // __uninitialized_copy-->__uninitilaized_copy_aux
// 是为利用编译器的类型参数推导,判断是否是POD类型
template <class InputIterator, class ForwardIterator, class T>
inline ForwardIterator
__uninitialized_copy(InputItearator first, InputIeratorlast,
ForwardIterator result, T*)
{
// is_POD 是一种类型,或者是__true_type代表为真,__
// false_type代表为否,假
// 利用is_POD的不同定义,生成不同的临时对象,用其进行重载
typedef typename __type_traits<T>::is_POD_type is_POD;
return __uninitialized_copy_aux(first, last, result, is_POD());
} // uninitialized_copy 的函数模板
// uninitialized_copy -> __uninitialized_copy
// 利用编译器的类型推导,萃取处迭代器指向的类型
// 以便最后通过类型萃取__type_traits机制获取迭代器指向类型的一些属性
template <class InputIterator, class ForwardIterator>
inline ForwardIterator
uninitialized_copy(InputIterator first, InputIterator last,
ForwardIterator result)
{
// value_type是个模板函数,萃取迭代器指向类型,用该类型生成临时对象,
// 再利用类型推导
return __uninitialized_copy(first, last, result, value_type(result)); } // uninitialized_copy 对于char* 的特化版本
inline char* uninitialized_cpoy(const char* first, const char* last,
char* result)
{
//对于char *对其使用memmove效率最高
memmove(result, first, last - first);
return result + (last - first);
} // unitialized_copy 对于 wchar_t* 的特化版本
inline wchar_t* uninitialized_copy(const wchar_t* first,
const wchar_t* last, wchar_t* result)
{
//同样对于wchar_t *对其使用memmove效率最高
memmove(result, first, sizeof(wchar_t) * (last - first));
return result + (last - first);
} // uninitialized_copy_n 的实现 // input_iterator_tag 是迭代器的分类中的一种,利用迭代器分类类型的不同
// 可以进行重载,不同的迭代器的类型,会针对其有特定的最优实现
template <class InputItearator, class Size, class ForwardIterator>
pair<InputIterator, ForwardIterator>
__uninitialized_copy_n(InputIterator first, Size count,
ForwardIterator result, input_ierator_tag)
{
// 对于input_iterator_tag类型的迭代器,只能逐个调用构造
ForwardIterator cur = result;
__STL_TRY
{
for (; count > ; --count, ++first, ++cur)
construct(&*cur, *first);
return pair<InputIterator, ForwardIterator>(first, cur);
}
// commit or rollback
__STL_UNWIND(destroy(result, cur));
} template <class RandomAccessItearator, class Size, class ForwardIterator>
inline pair<RandomAccessIterator, ForwardIterator>
__uninitialized_copy_n(RandomAccessIterator first, Size count,
ForwardIterator result, random_ierator_tag)
{
// 对于random_iterator_tag类型的迭代器
// 可以利用first和count计算出last迭代器
// 然后利用uninitialized_copy(first, last, result)
// 然而对于input_iterator_tag,就不能
RandomAccessIterator last = first _count;
return make_pair(last, uninitialized_copy(first, last, result));
} template <class InputIterator, class Size, class ForwardIterator>
inline pair<InputIterator, ForwardIterator>
uninitialized_copy_n(InputIterator first, Size count,
ForwardIterator result)
{
// 利用模板函数iterator_category提取出first迭代器的分类型别
// 然后利用其型别进行重载,对于不同的型别进行不同的优化处理
return __uninitialized_copy_n(first, count, result,
iterator_category(first));
} // uninitialized_fii 的实现 // 如果是POD型别,那么copy construction 等同于 assignment,而且
// destructor 是trivial,以下就有效
// 执行流程就会转进到以下函数。
template <class ForwardIterator, class T>
inline void
__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last,
const T& x, __true_type)
{
// isPOD的类型定义为__true_type,表示是POD类型
fill(first, last, x); //调用STL算法fill()
} template <class ForwardIterator, class T>
void
__uninitialized_fill_aux(ForwardIterator first, ForwardIterator last,
const T& x, __false_type)
{
// is_POD定义为__false_type表示不是POD类型,所以只能逐个构造
ForwardIterator cur = first;
__STL_TRY
{
for (; cur != last; ++cur)
construct(&*cur, x);
}
// commit or rollback
__STL_UNWIND(destroy(first, cur));
} // 内部的第二层,用于提取迭代器指向的类型是否是POD类型
// 并利用其进行重载
template <class ForwardIterator, class T, class T1>
inline void __uninitialized_fill(ForwardIterator first,
ForwardIterator last, const T& x, T1*)
{
// 利用__type_traits来萃取is_POD_type定义的类型
// 并利用其调用更底层的重载实现
typedef typename __type_traits<T1>::is_POD_type is_POD;
__uninitialized_fill_aux(first, last, x, is_POD());
} // uninitialized_fill()对外接口
template <class ForwardIterator, class T>
inline void uninitialized_fill(ForwardIterator first, ForwardIterator last,
const T& x)
{
__uninitialized_fill(first, last, x, value_type(first));
} // uninitialized_fill_n的实现 // 基本原理于uninitialized_copy_n一样 template <class ForwardIterator, class Size, class T>
inline ForwardIterator
__uninitialized_fill_n_aux(ForwardIterator first, Size n,
const T& x, __true_type)
{
return fill_n(first, n, x);
} template <class ForwardIterator, class Size, class T>
ForwardIterator
__uninitialized_fill_n_aux(ForwardIterator first, Size n,
const T& x, __false_type)
{
ForwardIterator cur = first;
__STL_TRY
{
for (; n > ; --n, ++cur)
construct(&*cur, x);
return cur;
}
__STL_UNWIND(destroy(first, cur));
} template <class ForwardIterator, class Size, class T, class T1>
inline ForwardIterator __uninitialized_fill_n(ForwardIterator first,
Size n, const T& x, T1*)
{
typedef typename __type_traits<T1>::is_POD_type is_POD;
return __uninitialized_fill_n_aux(first, n, x, is_POD());
} // uninitialized_fill_n对外接口
template <class ForwardIterator, class Size, class T>
inline ForwardIterator uninitialized_fill_n(ForwardIterator first,Size n,
const T& x)
{
return __uninitialized_fill_n(first, n, value_type(first));
} // 拷贝[first1, last1)到[result, result + (last1 - first1))
// 同时拷贝[first2, last2)到
// [result + (last1 - first1), result + (last1 - first1) + (last2 - first2)] template <class InputIterator1, class InputIterator2, class ForwardIterator>
inline ForwardIterator
__uninitialized_copy_copy(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator last2, ForwardIterator result)
{
ForwardIterator mid = uninitialized_copy(first1, last1, reuslt);
__STL_TRY
{
return uninitialized_copy(first2, last2, mid);
}
__STL_UNWIND(destroy(result, mid));
} // 用x填充[result, mid),同时拷贝[first, last)到[mid, mid + (last - first))
template <class ForwardIterator, class T, class InputIterator>
inline ForwardIterator
__uninitialized_fill_copy(ForwardIterator result, ForwardIterator mid,
const T& x, InputIterator first, InputIterator last)
{
uninitialized_fill(result, mid, x);
__STL_TRY
{
return uninitialized_copy(first, last, mid);
}
__STL_UNWIND(destroy(result, mid));
} // 拷贝[first1, last1)到[first2, first2 + (last1 - first1))
// 并且用x填充[first2 + (last1 - first1), last2]
template <class InputIterator, class ForwardIterator, class T>
inline void
__uninitialized_copy_fill(InputIterator first1, InputIterator last1,
ForwardIterator first2, ForwardIterator last2,
const T& x)
{
ForwardIterator mid2 = uninitialized_copy(first1, last1, first2);
__STL_TRY
{
uninitialized_fill(mid2, last2, x);
}
__STL_UNWIND(destroy(first2, mid2));
} __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_UNINITIALIZED_WJZH_H*/ // End

自己动手实现STL 03:内存基本处理工具(stl_uninitialized.h)的更多相关文章

  1. 自己动手实现STL 01:内存配置器的实现(stl_alloc.h)

    一.前言 在STL中,容器是其中的重中之重,基本的STL中的算法,仿函数等都是围绕着容器实现的功能.而,内存配置器,是容器的实现的基础.所以,我第一次要去编写便是内存配置器的实现.在STL中,内存配置 ...

  2. 自己动手实现STL:前言

    一.前言 最近,刚看完<STL源码剖析>,深深被实现STL库的那些的大牛们所折服.同时又感觉自己与大牛们差距之大,便萌生深入学习之意.如果仅仅只是看看<STL源码剖析>的话,又 ...

  3. STL的内存管理

    SGI STL 的内存管理 http://www.cnblogs.com/sld666666/archive/2010/07/01/1769448.html 1. 好多废话 在分析完nginx的内存池 ...

  4. STL之内存处理工具

    STL处理内存主要是使用五个全局函数construct,deconstruct,construct实现: template<typename T1,tyname T2> void cons ...

  5. Cocos开发中性能优化工具介绍之Visual Studio内存泄漏检测工具——Visual Leak Detector

    那么在Windows下有什么好的内存泄漏检测工具呢?微软提供Visual Studio开发工具本身没有什么太好的内存泄漏检测功能,我们可以使用第三方工具Visual Leak Detector(以下简 ...

  6. vld,Bounds Checker,memwatch,mtrace,valgrind,debug_new几种内存泄露检测工具的比较,Valgrind Cheatsheet

    概述 内存泄漏(memory leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况,在大型的.复杂的应用程序中,内存泄漏是常见的问题.当以前分配的一片内存不再需要使用或无法访问时,但是却 ...

  7. stl_内存基本处理工具

    内存基本处理工具 STL定义5个全局函数.作用于初始化空间上.各自是:用于构造的construct(),用于析构的destroy(),uninitialized_copy(),uninitialize ...

  8. 统计和分析系统性能【IO CPU 内存】的工具集合

    统计和分析系统性能[IO CPU 内存]的工具集合 blktrace http://www.oschina.net/p/blktrace 获取磁盘写入的信息 root@demo:~/install/p ...

  9. 内存泄漏检测工具Valgrind

    1概述 1.1 介绍 Valgrind是一套Linux下,开放源代码(GPL V2)的仿真调试工具的集合.Valgrind由内核(core)以及基于内核的其他调试工具组成.内核类似于一个框架(fram ...

随机推荐

  1. MyBatis 学习总结(1)

    MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架,几乎消除了所有的 JDBC 代码和参数的手工设置以及结果集的处理,通过XML(sqlMapConfig)或注解配置数据源和 ...

  2. 核PCA与PCA的精髓和核函数的映射实质

    1.PCA简介 遭遇维度危机的时候,进行特征选择有两种方法,即特征选择和特征抽取.特征选择即经过某种法则直接扔掉某些特征,特征抽取即利用映射的方法,将高维度的样本映射至低维度.PCA(或者K-L变换) ...

  3. 进程中t.start(), t.daemon() t.jion()的使用

    #!/usr/bin/env python import multiprocessing import time def f1(a1): time.sleep(2) print(a1) if __na ...

  4. [51nod1272]最大距离(贪心)

    解题关键:对num进行排序,从前往后扫id,及时更新 #include<cstdio> #include<cstring> #include<algorithm> ...

  5. Flask14 渲染问题、API、项目文档

    3 前端渲染和后端渲染 这两种渲染都属于动态页面 区分前后端渲染的关键点是站在浏览器的角度 3.1 后端渲染 浏览器请求服务器后获取到的是完整的HTML页面(即:后台已经组装好HTML文件啦),利用f ...

  6. java连接sqlserver2005数据库

    java连接sqlserver2005数据库   首先得下载驱动程序到微软网站下载Microsoft JDBC Driver 4.0 for SQL Server 下载地址 :http://msdn. ...

  7. Getting the System Version

    #include <windows.h>#include <tchar.h>#include <stdio.h>#include <strsafe.h> ...

  8. 7.SSRF漏洞绕过IP限制

    绕过SSRF过滤的几种方法 下文出现的192.168.0.1,10.0.0.1全部为服务器端的内网地址. 1.更改IP地址写法 一些开发者会通过对传过来的URL参数进行正则匹配的方式来过滤掉内网IP, ...

  9. 发现fork容易出错的一个地方

    今天在看代码时发现一段有意思的代码 #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include ...

  10. 介绍一款“对话框”组件之 “artDialog”在项目中的使用

    在实际开发项目中经常会用到对话框组件,提示一些信息.其实有很多,例如:在项目中常用到的“Jquery-UI.Jquery-EasyUI”的.Dialog,他们也很强大,Api文档也很多.今天就介绍一款 ...