本例写一个小的程序来进行std::string的allocate和free测试。
通过重载operator new和operator delete操作符,可以看到std::string分配和释放堆内存的全过程。
本例有一个flag new_instrumentation_on用于开启是否打印调试信息。
代码如下,
conanfile.txt
[requires]
boost/1.72.0
[generators]
cmake
CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
project(optimize)
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/lib/pkgconfig/")
set ( CMAKE_CXX_FLAGS "-pthread")
set(CMAKE_CXX_STANDARD 17)
add_definitions(-g)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
LINK_DIRECTORIES(${LINK_DIRS})
file( GLOB main_file_list ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
file( GLOB source_file_list ${CMAKE_CURRENT_SOURCE_DIR}/impl/*.cpp)
foreach( main_file ${main_file_list} )
file(RELATIVE_PATH filename ${CMAKE_CURRENT_SOURCE_DIR} ${main_file})
string(REPLACE ".cpp" "" file ${filename})
add_executable(${file} ${main_file} ${source_file_list})
target_link_libraries(${file} ${CONAN_LIBS} pthread)
endforeach( main_file ${main_file_list})
allocator_test.cpp
#include <iostream>
#include <memory>
#include <string>
bool static new_instrumentation_on = false;
void instrument_new(bool f = true) {
new_instrumentation_on = f;
}
// std::hex 转16进制输出
// std::dec 转10进制输出
// std::oct 转8进制输出
void* operator new(std::size_t size) {
void *p = malloc(size);
if(new_instrumentation_on) {
std::cout << "new (" << size << ") allocated at 0x" << std::hex << p << std::dec << std::endl;
}
return p;
}
void operator delete(void *p) {
if(new_instrumentation_on) {
std::cout << "delete 0x" << std::hex << p << std::dec << std::endl;
}
free(p);
}
int string_allocator_test() {
instrument_new();
{
puts("std::string s");
std::string s;
puts("try appending one char");
s = s + 'x';
puts("try appending 20 char C-style string");
s = s + "12345678901234567890";
puts("try appending s");
s = s + s;
puts("for");
for(int i=0; i<30; ++i) {
s = s + 'x';
}
puts("delete s");
}
instrument_new(false);
return 1;
}
int main(int argc, char* argv[]) {
string_allocator_test();
return EXIT_SUCCESS;
}
程序输出如下,表明如果要频繁的连接字符串,使用+= 操作符操作字符,最好先用reserve保留足够的内存,否则会一直动态分配和释放内存,影响效率。
image.png
网友评论