1.1 变量存储域 int a = 0; //全局区 void main() { int b; //栈 char s[] = “abc”; //s在栈,abc在文字常量区 char *p1,*p2; //栈 char *p3 = "123456"; //123456在常量区,p3在栈上 static int c =0; //全局区 p1 = (char *)malloc(10); //p1在栈,分配的10字节在堆 p2 = (char *)malloc(20); //p2在栈,分配的20字节在堆 strcpy(p1, "123456"); //123456放在常量区 } 这个代码示例中出现了“全局区”,“栈”,“文字常量区”,“堆”等词语。为了统一,我们使用《C专家编程》中的说法:堆栈段,BSS段,数据段,文本段。 各个段的作用如下: 1、 文本段:包含程序的指令,它在程序的执行过程中一般不会改变。 2、 数据段:包含了经过初始化的全局变量和静态变量,以及他们的值。 3、 BSS段:包含未经初始化的全局变量和静态变量。 4、 堆栈段:包含了函数内部声明的局部变量。 当然,上面段的作用不仅于此,具体的作用会在下面的知识点中介绍。 1.1.2 通过代码测试变量的存储位置
下面通过代码示例和“size”来研究变量的存储区域。 test.c int main() { return 1; } 编译,并且查看可执行程序各个段的大小:
更改test.c: int g_data; int main() { return 1; } 编译,并且查看可执行程序各个段的大小:
可以发现,文本段,数据段都没有发送变化,而BSS段增加了4个字节。 结论1:未初始化的全局变量保存在BSS段中 继续: int g_data = 1; int main() { return 1; } 编译:
可以发现,BSS段和文本段相同,而数据段增加了4个字节。 结论2:经过初始化的全局变量保存在数据段中 继续: int main() { static int g_data; return 1; } 编译:
可以发现,文本段,数据段都没有发送变化,而BSS段增加了4个字节。 结论3:未初始化的静态变量保存在BSS段中 继续: int main() { static int g_data = 1; return 1; } 编译:
可以发现,BSS段和文本段相同,而数据段增加了4个字节。 结论4:经过初始化的静态变量保存在数据段中 继续: int main() { int i_data = 1; return 1; } 编译:
可以发现,BSS段和和数据段相同,而文本段增加了16个字节。局部变量会在执行的时候在堆栈段中生成,函数执行完毕后释放。 结论5:函数内部声明的局部变量保存在堆栈段中 继续: const int g_data = 1; int main() { return 1; } 编译:
把全局变量定义为“const”后,也许你会感到奇怪,怎么BSS段和数据段都没有发生变化,而文本段却增加了4个字节。 结论6:const修饰的全局变量保存在文本段中 那么,const的局部变量? 继续: int main() { const int i_data = 1; return 1; } 编译:
结论7:const修饰的局部变量保存在堆栈段中 继续: char *pstr = ""; int main() { return 1; } 编译:
在做一下更改: char *pstr = "123456789"; int main() { return 1; } 编译:
可以发现,前后数据段和BSS段大小均未发生变化,而文本段增加了9个字节。 结论8:字符串常量保存在文本段中 1.1.3 结论 2、 未经初始化的全局变量和静态变量保存在BSS段。 3、 函数内部声明的局部变量保存在堆栈段中。 4、 const修饰的全局变量保存在文本段中,const修饰的局部变量保存在堆栈段中。 5、 字符串常量保存在文本段中。 1.1.4 扩展阅读
|