一直以来对堆与栈的理解是有点模糊。
起初只是知道栈空间是连续的;因为这种特性,使栈的操作与使用比较简单,基本操作就是指针上下移动就行了。而堆的空间分布可以是不连续的,因为这个原因会带来操作上的一些繁琐,比如进行搜索时会出现不必要的步骤,但在另一方面来说提高了灵活性。
但是对于程序来说,数据应该在什么情况下分配到栈空间,什么情况下分配到堆空间呢?
应该可以这样理解:
1.没有引用类型的值类型会在栈空间里分配,比如struct,局部变量的int等。
2.至于包含了引用类型的:引用类型可以分成两部分,一部分是它的"引用",分配在栈空间里;一部分是实际内容,分配在堆空间里。
应该可以这样举例,'引用'就是一条街的地址名,通过这个地址名就可以找到这条街。那么这地址名是放在栈里,真实的街道则是在堆空间里了。
以上是个人的一些粗浅理解。
写到这里,有点纠结,感觉这方面还是有很多知识不够理解。不知道知道了这些会有多大用处,但知道堆和栈的一些知识还是有益的吧。
以下是参考资料,仅作读书笔记:
一般认为在c中分为这几个存储区:
1. 栈 --有编译器自动分配释放
2. 堆 -- 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收
3. 全局区(静态区) -- 全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束释放。
4. 另外还有一个专门放常量的地方。程序结束释放
在函数体中定义的变量通常是在栈上,用malloc, calloc, realloc等分配内存的函数分配得到的就是在堆上。在所有函数体外定义的是全局量,加了static修饰符后不管在哪里都存放在全局区(静态区),在所有函数体外定义的static变量表示在该文件中有效,不能extern到别的文件用,在函数体内定义的static表示只在该函数体内有效。另外,函数中的"adgfdf"这样的字符串存放在常量区。 比如:
代码:
//main.cpp
int a = 0; 全局初始化区
char *p1; 全局未初始化区
main()
{
int b; 栈
char s[] = "abc"; 栈
char *p2; 栈
char *p3 = "123456"; 123456\0在常量区,p3在栈上。
static int c =0; 全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20); 分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456"); 123456\0放在常量区,编译器可能会将它与p3所指向
的"123456"优化成一个地方
}
起初只是知道栈空间是连续的;因为这种特性,使栈的操作与使用比较简单,基本操作就是指针上下移动就行了。而堆的空间分布可以是不连续的,因为这个原因会带来操作上的一些繁琐,比如进行搜索时会出现不必要的步骤,但在另一方面来说提高了灵活性。
但是对于程序来说,数据应该在什么情况下分配到栈空间,什么情况下分配到堆空间呢?
应该可以这样理解:
1.没有引用类型的值类型会在栈空间里分配,比如struct,局部变量的int等。
2.至于包含了引用类型的:引用类型可以分成两部分,一部分是它的"引用",分配在栈空间里;一部分是实际内容,分配在堆空间里。
应该可以这样举例,'引用'就是一条街的地址名,通过这个地址名就可以找到这条街。那么这地址名是放在栈里,真实的街道则是在堆空间里了。
以上是个人的一些粗浅理解。
写到这里,有点纠结,感觉这方面还是有很多知识不够理解。不知道知道了这些会有多大用处,但知道堆和栈的一些知识还是有益的吧。
以下是参考资料,仅作读书笔记:
一般认为在c中分为这几个存储区:
1. 栈 --有编译器自动分配释放
2. 堆 -- 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收
3. 全局区(静态区) -- 全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束释放。
4. 另外还有一个专门放常量的地方。程序结束释放
在函数体中定义的变量通常是在栈上,用malloc, calloc, realloc等分配内存的函数分配得到的就是在堆上。在所有函数体外定义的是全局量,加了static修饰符后不管在哪里都存放在全局区(静态区),在所有函数体外定义的static变量表示在该文件中有效,不能extern到别的文件用,在函数体内定义的static表示只在该函数体内有效。另外,函数中的"adgfdf"这样的字符串存放在常量区。 比如:
代码:
//main.cpp
int a = 0; 全局初始化区
char *p1; 全局未初始化区
main()
{
int b; 栈
char s[] = "abc"; 栈
char *p2; 栈
char *p3 = "123456"; 123456\0在常量区,p3在栈上。
static int c =0; 全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20); 分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456"); 123456\0放在常量区,编译器可能会将它与p3所指向
的"123456"优化成一个地方
}