【C】內存操做經典問題分析二

常見內存錯誤

結構體成員指針未初始化
結構體成員指針未分配足夠的變量
內存分配成功,但並未初始化
內存操做越界

例子42-1:函數

#include "stdio.h"
#include "malloc.h"
void test(int* p,int size)
{
    int i = 0;
    for(i = 0; i < size; i++)
    {
        printf("%d\n",p[i]);
    }
//    free(p);
}
void func(unsigned int size)
{
     int *p = (int*)malloc(size *sizeof(int));
     int i = 0;
     if(size % 2 != 0)
     {
        return;
     }
     for(i = 0; i < size; i++)
     {
        p[i] = i;
        printf("%d\n",p[i]);
     }
     free(p);
}
int main()
{
    int* p = (int*)malloc(5 * sizeof(int));  //在main函數裏面申請的動態內存,就要在main函數裏面釋放
    test(p , 5);
    free(p);
    func(9);
    func(9);
    return 0;
}

輸出結果:指針

func函數會產生內存泄漏,若是是基數就會直接return,致使內存沒有釋放,形成內存泄漏

例子42-2:code

#include "stdio.h"
#include "malloc.h"
struct Demo
{
    char *p;
}
int main()
{
    struct Demo d1;
    struct Demo d2;
    char i = 0;
    for(i = 'a';i < 'z';i ++) 
    {
        d2.p[i] = 0;
    }
    d2.p = (char*)calloc(5,sizeof(char));
    printf("%s\n",d2.p);
    for(i = 'a';i < 'z';i ++) //內存越界
    {
        d2.p[i] = i;
    }
    free(d2.p);
    return 0;
}

內存操做的規則

規則一:

動態內存申請以後,應該當即檢查指針值是否爲NULL,防止使用NULL指針。內存

int* p = (int*)malloc(56);
if(p != NULL)
{

}
free(p);
規則二:

free指針以後必須當即賦值爲NULLio

int* p = (int*)malloc(20);
free(p);
p = NULL;
//......
//......
if(p != NULL)
{

}
規則三:

任何與內存操做相關的函數必須帶長度信息test

void print(int* p,int size)
{
    int i = 0;
    char buf[128] = {0};
    snprintf(buf,sizeof(buf),"%s","D.T.Software");
    for(i = 0;i < size; i++)
    {
        printf("%d\n",p[i]);
    }
}
規則四:

malloc操做和free操做必須匹配,防止內存泄漏和屢次釋放。不要跨函數釋放內存。變量

void func()
{
    int* p = (int*)malloc(20);
    free(p);
}
int main()
{
    int* p = (int*)malloc(20);
    func();
    free(p);
    return 0;
}

小結:

內存錯誤的本質源於指針保存的地址爲非法值
指針變量未初始化,保存隨機值
指針運算致使內存越界
內存泄漏於malloc和free不匹配
當malloc次數多於free時,產生內存泄漏
當malloc次數少於free時,程序可能崩潰
相關文章
相關標籤/搜索