導航
- ??前言??
- 🍃常見記憶體錯誤
- 🍂對NULL指標的解參考操作
- 🍂越界訪問
- 🍂對非動態開辟記憶體使用free釋放
- 🍂使用free釋放一塊動態開辟記憶體的一部分
- 🍂對同一塊動態記憶體多次釋放
- 🍂記憶體泄漏
- 🍃動態記憶體錯誤筆試題分析
- 🍂筆試題1
- 🍂筆試題2
- 🍂筆試題3
- 🍂筆試題4
- ??結尾語??
??前言??
經過前面動態記憶體相關知識的學習,我們本文就要來分析動態記憶體相關的問題,
🍃常見記憶體錯誤
🍂對NULL指標的解參考操作
void test(){
int* p = (int*)malloc(INT_MAX*sizeof(int));
*p = 20;//如果p的值是NULL,就會有問題
free(p);
}
🍂越界訪問
void test(){
int i = 0;
int* p = (int*)malloc(10 * sizeof(int));
if (NULL == p){
exit(EXIT_FAILURE);
}
for (i = 0; i <= 10; i++){
*(p + i) = i;//當i是10的時候越界訪問
}
free(p);
}
🍂對非動態開辟記憶體使用free釋放
void test(){
int a = 10;
int* p = &a;
free(p);//ok?
}
🍂使用free釋放一塊動態開辟記憶體的一部分
void test() {
int* p = (int*)malloc(100);
p++;
free(p);//p不再指向動態記憶體的起始位置
}
🍂對同一塊動態記憶體多次釋放
void test(){
int* p = (int*)malloc(100);
free(p);
free(p);//重復釋放
}
🍂記憶體泄漏
void test(){
int* p = (int*)malloc(100);
if (NULL != p){
*p = 20;
}
}
int main(){
test();
while (1);
}
🍃動態記憶體錯誤筆試題分析
🍂筆試題1
以下代碼執行效果
void GetMemory(char* p){
p = (char*)malloc(100);
}
void Test(){
char* str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf("%s",str);
}
int main() {
Test();
return 0;
}
執行后:程式會崩潰
分析如下:
我們經過除錯發現再執行GetMemory(str); 后str的地址還是等于NULL,那這是為什么呢?
那肯定是這個函式處理不當?
突然想起函式傳遞引數–傳值呼叫,如下
void change(int a) {
a = a + 1;
}
int main() {
int a = 0;
change(a);
return 0;
}
在執行完后看似a的值加一,但是我們發現它還是0
對于這種情況也是一樣,傳值呼叫并不能改變值,要想達到目的需要進行傳址呼叫,
void GetMemory(char** p){
*p = (char*)malloc(100);
}
void Test(){
char* str = NULL;
GetMemory(&str);
strcpy(str, "hello world");
printf(str);
}
int main() {
Test();
return 0;
}

🍂筆試題2
char* GetMemory(void){
char p[] = "hello world";
return p;
}
void Test(void){
char* str = NULL;
str = GetMemory();
printf(str);
}
int main() {
Test();
return 0;
}
輸出隨機值
str接受了p的地址,但是在GetMemory函式結束后銷毀,p函式中記憶體內容也被隨機化,雖然拿到了地址,但是內容不再是hello world
這種情況對應野指標,指標指向的內容已被釋放,對其解參考就會出錯
int* change() {
int n = 10;
return &n;
}
int main() {
int* p = change();
printf(" \n");
printf("%d", *p);
return 0;
}
輸出的不是我們想要的10
🍂筆試題3
void GetMemory(char** p, int num){
*p = (char*)malloc(num);
}
void Test(void){
char* str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}
int main() {
Test();
return 0;
}
這道題就是筆試題1的正確寫法,輸出
hello
🍂筆試題4
void Test(void){
char* str = (char*)malloc(100);
strcpy(str, "hello");
free(str);
if (str != NULL){
strcpy(str, "world");
printf(str);
}
}
int main() {
Test();
return 0;
}
輸出hello,word
分析:
對于第一個輸出hello很容易判斷,在釋放后str的內容雖然丟失了,但是str的地址還在,不為空,所以world被拷貝進去,

這也是前文介紹在釋放后需要把指標指向NULL
??結尾語??
相關鏈接
??上一篇:動態記憶體管理知識??
??下一篇:暫未更新??
??傳值呼叫以及傳值呼叫:函式??
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/304980.html
標籤:其他

