C++ 查看内存字节对齐方式的简单方法

2023-10-20  本文已影响0人  FredricZhu

在一些内存较小的嵌入式设备上,经常需要节约使用内存。
在C++中,内存对齐方式有一定的规则。具体这些规则我也记不住。平时也不咋用。
但是从性能优化指南这本书里面找到了查看内存对齐规则的一个小方法。
offsetof。
程序代码如下,
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 atomic)
endforeach( main_file ${main_file_list})

struct_offset_test.cpp

#include "test_driver.h"
#include <iostream>

int test_struct_offset(int, unsigned long);

int (*func[])(int, unsigned long) = {
    test_struct_offset,
    0
};

int main(int argc, char* argv[]) {
    test_driver(func, argc, argv);
    return EXIT_SUCCESS;
}

struct_offset_impl.cpp

#include <iostream>
#include <cstddef>

int test_struct_offset(int test_no, unsigned long multiplier) {
    bool rc = true;
    switch (test_no){
    default: return -1;
    case 0: return 2;
    case 1: return 1;

    case 2: {
        struct S1 {
            char c1;
            short s1;
            double d1;
            int i1;
            char c2;
        };

        std::cout << "size of struct S1: " << sizeof(S1) << std::endl
            << "    offset of c1: " << offsetof(S1, c1) << std::endl
            << "    offset of s1: " << offsetof(S1, s1) << std::endl 
            << "    offset of d1: " << offsetof(S1, d1) << std::endl
            << "    offset of i1: " << offsetof(S1, i1) << std::endl
            << "    offset of c2: " << offsetof(S1, c2) << std::endl;


        struct S1a {
            struct S1 s1;
            char c3;
        };

        std::cout << "size of struct S1a: " << sizeof(S1a) << std::endl
            << "    offset of c3: " << offsetof(S1a, c3) << std::endl;

        
        // 16 字节紧凑排布,内存布局
        struct S2 {
            char c1; 
            char c2;
            short s1;
            int i1;
            double d1;
        };

        std::cout << "size of struct S2: " << sizeof(S2) << std::endl
                << "    offset of c1: " << offsetof(S2, c1) << std::endl
                << "    offset of c2: " << offsetof(S2, c2) << std::endl
                << "    offset of s1: " << offsetof(S2, s1) << std::endl
                << "    offset of i1: " << offsetof(S2, i1) << std::endl
                << "    offset of d1: " << offsetof(S2, d1) << std::endl;
    }
        break;
    }

    return (rc) ? 1: 0;
}

程序输出如下,
可以看到struct S1和S2字段基本一样,只是排序不同。然后S2更紧凑,在内存中少了8个字节。


image.png
上一篇 下一篇

猜你喜欢

热点阅读