由系統(tǒng)進行內(nèi)存的管理。主要存放函數(shù)的參數(shù)以及局部變量。在函數(shù)完成執(zhí)行,系統(tǒng)自行釋放棧區(qū)內(nèi)存,不需要用戶管理。
char* func(){
char p[] = "hello world!"; //在棧區(qū)存儲 亂碼
printf("%s\n", p);
return p;
}
void test(){
char* p = NULL;
p = func();
printf("%s\n",p);
}
結(jié)果第一次可以輸出,第二次輸出亂碼
由編程人員手動申請,手動釋放,若不手動釋放,程序結(jié)束后由系統(tǒng)回收,生命周期是整個程序運行期間。使用malloc或者new進行堆的申請。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
char* func() {
char* str = (char*)malloc(100);
strcpy(str, "hello world!");
printf("%s\n", str);
return str;
}
void test01() {
char* p = NULL;
p = func();
printf("%s\n", p);
}
void allocateSpace(char* p) {
p = (char*)malloc(100);
strcpy(p, "hello world!");
printf("%s\n", p);
}
void test02() {
char* p = NULL;
allocateSpace(p);
printf("%s\n", p);
}
int main()
{
test01();
test02();
}
#include <stdlib.h>
void *calloc(size_t nmemb, size_t size);
nmemb
:所需內(nèi)存單元數(shù)量size
:每個內(nèi)存單元的大小(單位:字節(jié))#include <stdlib.h>
void *realloc(void *ptr, size_t size);
ptr
:為之前用malloc或者calloc分配的內(nèi)存地址,如果此參數(shù)等于NULL,那么和realloc與malloc功能一致size
:為重新分配內(nèi)存的大小, 單位:字節(jié)#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void test01() {
int* p1 = (int *)calloc(10, sizeof(int));
if (p1 == NULL) {
return;
}
for (int i = 0; i < 10; i++) {
p1[i] = i + 1;
}
for (int i = 0; i < 10; i++) {
printf("%d ", p1[i]);
}
printf("\n");
free(p1);
}
void test02() {
int* p1 = (int *)calloc(10, sizeof(int));
if (p1 == NULL) {
return;
}
for (int i = 0; i < 10; i++) {
p1[i] = i + 1;
}
int* p2 = (int *)realloc(p1, 15 * sizeof(int));
if (p2 == NULL) {
return;
}
printf("P1=%d\n", p1);
printf("P2=%d\n", p2);
//打印
for (int i = 0; i < 15; i++) {
printf("%d ", p2[i]);
}
printf("\n");
//重新賦值
for (int i = 0; i < 15; i++) {
p2[i] = i + 1;
}
//再次打印
for (int i = 0; i < 15; i++) {
printf("%d ", p2[i]);
}
printf("\n");
free(p2);
}
int main()
{
test01();
test02();
return 0;
}
全局靜態(tài)區(qū)內(nèi)的變量在編譯階段已經(jīng)分配好內(nèi)存空間并初始化。
這塊內(nèi)存在程序運行期間一直存在,它主要存儲全局變量、靜態(tài)變量和常量。
例如:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int v1 = 10;//全局/靜態(tài)區(qū)
const int v2 = 20;//常量,一旦初始化,不可修改
static int v3 = 20; //全局/靜態(tài)區(qū)
char *p1;//全局/靜態(tài)區(qū),編譯器默認初始化為NULL
void test() {
static int v4 = 20; //全局/靜態(tài)區(qū)
}
int main()
{
test();
return 0;
}
關(guān)于靜態(tài)全局變量與非靜態(tài)全局變量的討論,內(nèi)容過多,大家可以看下面一篇文章:
https://yangyongli.blog.csdn.net/article/details/120402589
1.若全局變量僅在單個C文件中訪問,則可以將這個變量修改為靜態(tài)全局變量,以降低模塊間的耦合度;
2.若全局變量僅由單個函數(shù)訪問,則可以將這個變量改為該函數(shù)的靜態(tài)局部變量,以降低模塊間的耦合度;
3.設(shè)計和使用訪問動態(tài)全局變量、靜態(tài)全局變量、靜態(tài)局部變量的函數(shù)時,需要考慮重入問題,因為他們都放在靜態(tài)數(shù)據(jù)存儲區(qū),全局可見;
4.如果我們需要一個可重入的函數(shù),那么,我們一定要避免函數(shù)中使用static變量(這樣的函數(shù)被稱為:帶“內(nèi)部存儲器”功能的的函數(shù))
5.函數(shù)中必須要使用static變量情況:比如當某函數(shù)的返回值為指針類型時,則必須是static的局部變量的地址作為返回值,若為auto類型,則返回為錯指針。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char* func() {
static char arr[] = "hello world!"; //在靜態(tài)區(qū)存儲 可讀可寫
arr[2] = 'c';
const char* p = "hello world!"; //全局/靜態(tài)區(qū)-字符串常量區(qū)
//p[2] = 'c'; //只讀,不可修改
printf("%d\n", arr);
printf("%d\n", p);
printf("%s\n", arr);
return arr;
}
void test() {
char* p = func();
printf("%s\n", p);
}
int main()
{
test();
return 0;
}
數(shù)據(jù)區(qū)包括:堆,棧,全局/靜態(tài)存儲區(qū)。
全局/靜態(tài)存儲區(qū)包括:常量區(qū),全局區(qū)、靜態(tài)區(qū)。
常量區(qū)包括:字符串常量區(qū)、常變量區(qū)。
代碼區(qū):存放程序編譯后的二進制代碼,不可尋址區(qū)。
可以說,C/C++內(nèi)存分區(qū)其實只有兩個,即代碼區(qū)和數(shù)據(jù)區(qū)。
聯(lián)系客服