文档章节

认识bss段和data段

n
 nodouble
发布于 2015/09/09 20:42
字数 1199
阅读 103
收藏 0

    先直接贴上一段wikipedia中的描述:

BSS in C

In C, statically-allocated objects without an explicit initializer are initialized to zero (for arithmetic types) or a null pointer (for pointer types). Implementations of C typically represent zero values and null pointer values using a bit pattern consisting solely of zero-valued bits (though this is not required by the C standard). Hence, the BSS segment typically includes all uninitialized objects (both variables and constants) declared at file scope (i.e., outside any function) as well as uninitialized static local variables (local variables declared with the static keyword); static local constants must be initialized at declaration, however, as they do not have a separate declaration, and thus are typically not in the BSS section, though they may be implicitly or explicitly initialized to zero. An implementation may also assign statically-allocated variables and constants initialized with a value consisting solely of zero-valued bits to the BSS section.

Peter van der Linden, a C programmer and author, says, "Some people like to remember it as 'Better Save Space.' Since the BSS segment only holds variables that don't have any value yet, it doesn't actually need to store the image of these variables. The size that BSS will require at runtime is recorded in the object file, but BSS (unlike the data segment) doesn't take up any actual space in the object file."[4]

Data

The data area contains global and static variables used by the program that are explicitly initialized with a non-zero (or non-NULL) value. This segment can be further classified into a read-only area and read-write area. For instance, the string defined by char s[] = "hello world" in C, or a C statement like int debug = 1 outside the main function, would be stored in initialized read-write area. Also, a C statement like const char* string = "hello world", placed outside the main function, stores the string literal "hello world" in the read-only area (however, some C implementations may store it in the code segment instead), and the character pointer variable string in initialized read-write area.

BSS

The BSS segment, also known as uninitialized data, is usually adjacent to the data segment. The BSS segment contains all global variables and static variables that are initialized to zero or do not have explicit initialization in source code. For instance, a variable defined as static int i; would be contained in the BSS segment.


简单说来,Data段中存放的是显式初始化为非0值的全局或静态变量,并会占据目标文件空间,而Bss段中存放的是未初始化或初始化为0值的全局或静态变量,且不会实际占据目标文件的空间。

下面就通过几个实验来验证一下上述说法。

1)非静态局部变量

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]){
    
    int array[1024*1024] = {'a'};
    int i;

    printf("Hello World!\n");

    for(i=0; i<1024*1024; i++){
        array[i] += i;
    }
    
    printf("%d %d %d\n", array[0], array[1024], array[1024*1024-1]);

    printf("See You World!\n");

    return 0;
}

编译该程序并查看结果:

gcc -g -o bss bss.c

$ ls -l ./bss
-rwxrwxr-x 1 xxx xxx 9895 Sep  9 20:10 ./bss

$ size ./bss
text       data        bss        dec        hex    filename
1491        520         16       2027        7eb    ./bss

可见,程序大小为9895字节,data段和bss段的大小分别为520和16;


2)未初始化的静态局部变量

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]){
    
    static int array[1024*1024];
    int i;

    printf("Hello World!\n");

    for(i=0; i<1024*1024; i++){
        array[i] += i;
    }
    
    printf("%d %d %d\n", array[0], array[1024], array[1024*1024-1]);

    printf("See You World!\n");

    return 0;
}

查看结果:

$ ls -l ./bss
-rwxrwxr-x 1 xxx xxx 9870 Sep  9 20:26 ./bss

$ size ./bss
text       data        bss        dec        hex    filename
1386        512    4194336    4196234     40078a    ./bss

可见,目标文件大小为9870,与之前相比没有太大变化,通过size命令可以看到实际bss段的大小增长了很多;


3)初始化为非0值的静态局部变量

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]){
    
    static int array[1024*1024] = {'a'};
    int i;

    printf("Hello World!\n");

    for(i=0; i<1024*1024; i++){
        array[i] += i;
    }
    
    printf("%d %d %d\n", array[0], array[1024], array[1024*1024-1]);

    printf("See You World!\n");

    return 0;
}

查看结果:

$ ls -l ./bss
-rwxrwxr-x 1 xxx xxx 4204198 Sep  9 20:31 ./bss

$ size ./bss
text       data        bss        dec        hex    filename
1386    4194832         16    4196234     40078a    ./bss

可以看到,这时目标文件的大小增长了很多,同时通过size命令看到占用的是Data段;


4)未初始化的全局变量

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int array[1024*1024];

int main(int argc, char *argv[]){
    
    int i;

    printf("Hello World!\n");

    for(i=0; i<1024*1024; i++){
        array[i] += i;
    }
    
    printf("%d %d %d\n", array[0], array[1024], array[1024*1024-1]);

    printf("See You World!\n");

    return 0;
}

查看结果:

$ ls -l ./bss
-rwxrwxr-x 1 xxx xxx 9873 Sep  9 20:34 ./bss

$ size ./bss
text       data        bss        dec        hex    filename
1386        512    4194336    4196234     40078a    ./bss

可以看到,这时占用的是Bss段,且不会占据目标文件的空间;


5)初始化为非0的全局变量

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int array[1024*1024] = {'b'};

int main(int argc, char *argv[]){
    
    int i;

    printf("Hello World!\n");

    for(i=0; i<1024*1024; i++){
        array[i] += i;
    }
    
    printf("%d %d %d\n", array[0], array[1024], array[1024*1024-1]);

    printf("See You World!\n");

    return 0;
}

查看结果:

$ ls -l ./bss
-rwxrwxr-x 1 xxx xxx 4204201 Sep  9 20:38 ./bss

$ size ./bss
text       data        bss        dec        hex    filename
1386    4194832         16    4196234     40078a    ./bss

此时占用的是Data段,且会占用目标文件的空间;



好久没有写文章了,这篇略水,但也说明“实践出真知”,能够帮助我们更好的理解知识点;

希望对大家有帮助:)




© 著作权归作者所有

n
粉丝 3
博文 34
码字总数 40111
作品 0
东城
私信 提问
text, data and bss: 代码和数据的所占空间详解

本文原文:https://mcuoneclipse.com/2013/04/14/text-data-and-bss-code-and-data-size-explained/ In “Code Size Information with gcc for ARM/Kinetis” I use an option in the ARM g......

BetaYuan
2018/01/30
2.6K
0
关于gcc的变量内存问题,大家来看总结的对不对

linux下程序在内存中会分为这么几个段 代码段 数据段 bss段 堆 栈 其中,执行代码在代码段中(32位系统下,这个大小是.text + .rodata;但是在64位下,这个大小是.text + .rodata + .eh_fra...

NickWilde
2013/08/22
708
2
UBOOT的lds文件text地址的定义无效

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") /指定输出可执行文件是elf格式,32位ARM指令,小端/ OUTPUT_ARCH(arm) /指定输出可执行文件的平台为ARM/ ENTRY(_sta......

慎思
2012/09/17
445
0
C/C++内存模型

C分为四个区:堆,栈,静态全局变量区,常量区c++分为四个区:堆,栈,静态全局变量去,常量区,自由存储区。 根据c/c++对象生命周期不同,c/c++的内存模型有三种不同的内存区域,即自由存储...

MtrS
2016/12/08
36
0
BSS段和数据段

内存分段(英语:Memory segmentation),一种电脑内存的管理技术,它将电脑的主内存分成许多区段(segment或sections)。当处理器要进行内存定址时,会使用一个数值,这个数值包括了某个区段...

壶漏子
2016/12/10
12
0

没有更多内容

加载失败,请刷新页面

加载更多

[mycat]PartitionByString分片报错

java.lang.RuntimeException: error,check your partitionScope definition.at io.mycat.route.util.PartitionUtil.<init>(PartitionUtil.java:69) PartitionUtil.java 注意:其中count,l......

Danni3
13分钟前
6
0
OSChina 周三乱弹 —— 魂淡!不是这种粪发涂墙

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @小小编辑推荐歌曲《10/10》- Rex Orange County 《10/10》- Rex Orange County 手机党少年们想听歌,请使劲儿戳(这里) @奋斗的小牛 :上午...

小小编辑
25分钟前
496
7
Arduino教程:认识Arduino控制板

@toc 1.1 课程说明 认识Arduino控制板的各个部分, 1.2 器材 名称 数量 规格 Arduino uno控制板 1 R3 1.3 UNO电路: UNO参数 名称 参数说明 工作电压: 5V 输入电压: 接上USB时无须外部供电...

acktomas
31分钟前
6
0
WeUI框架

WeUI框架 WeUI是一套小程序的UI框架,所谓UI框架就是一套界面设计方案,有了组件,我们可以用它来拼接出一个内容丰富的小程序,而有了UI框架,我们就可以让我们的小程序变得更加美观。 体验W...

达达前端小酒馆
34分钟前
3
0
Rainbond 5.1.8发布,应用网关支持多IP网络接入

2019年10月23日,Rainbond发布5.1.8版本,本次版本更新带来了应用网关对多IP的支持, 第三方组件对域名实例的支持 等新功能和修复若干BUG。 Rainbond:支撑企业应用的开发、架构、交付和运维的...

好雨云帮
36分钟前
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部