美文网首页
C++ 查看内存字节对齐方式的简单方法

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

作者: FredricZhu | 来源:发表于2023-10-20 15:48 被阅读0次

在一些内存较小的嵌入式设备上,经常需要节约使用内存。
在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

相关文章

  • OC底层原理三:内存对齐分析

    获取内存大小 上一篇我们简单的提了下内存字节对齐以及为什么要内存字节对齐,那么我们首先看下有什么方式可以获取内存大...

  • sizeof与字节对齐

    参考 【面试题】sizeof引发的血案编译器与字节对齐c 语言字节对齐问题详解C/C++内存对齐内存存取粒度C和C...

  • #pragma pack(n)的使用

    pragma pack(n)用于修改内存对齐方式,n表示n字节对齐

  • 【待更新】C++中的字节对齐

    C++中的字节对齐

  • #pragma pack(push,1)与#pragma pac

    这是给编译器用的参数设置,有关结构体字节对齐方式设置, #pragma pack是指定数据在内存中的对齐方式。 #...

  • 手撕 iOS 底层04 -- 内存对齐原理

    本章主要由结构体内存对齐到苹果的属性重排, 以及16字节对齐算法 0x00 -- 获取内存大小的三种方式 获取内存...

  • #pragma pack&pop

    转这是给编译器用的参数设置,有关结构体字节对齐方式设置, #pragma pack是指定数据在内存中的对齐方式。 ...

  • 为什么要内存对齐?

    一. 什么是内存对齐(Memory alignment),也叫字节对齐 在计算机中,内存是按 字节(byte, 1...

  • 内存对齐

    内存对齐,或者说字节对齐,是代码编译后在内存的布局与使用方式。现代计算机一般是32比特或64比特地址对齐,如果要访...

  • 内存对齐

    内存对齐 什么叫内存对齐内存对齐就是按照特定的规则对数据进行存储,一般编译器按照8字节对齐标准处理。内存对齐一般用...

网友评论

      本文标题:C++ 查看内存字节对齐方式的简单方法

      本文链接:https://www.haomeiwen.com/subject/olnhidtx.html