GetMemory函數的幾種經典考法

來源:互聯網
上載者:User

//NO.1:程式首先申請一個char類型的指標str,並把str指向NULL(即str裡存的是NULL的地址,*str為NULL中的值為0),調用函數的過程中做了如下動作:1申請一個char 類型的指標p,2把str的內容copy到了p裡(這是參數傳遞過程中系統所做的),3為p指標申請了100個空間,4返回Test函數.最後程式把字串hello
world拷貝到str指向的記憶體空間裡.到這裡錯誤出現了!str的空間始終為NULL而並沒有實際的空間.深刻理解函數調用的第2步,將不難發現問題所在!
void GetMemory(char *p)
{
   p = (char*)malloc(100);
}

void Test(void)
{
   char *str = NULL;
   GetMemory(str);
   strcpy(str, "hello world");
   printf(str);
}
//請問運行Test函數後會是什麼樣的結果?

//NO.2:程式首先申請一個char類型的指標str,並把str指向NULL.調用函數的過程中做了如下動作:1申請一數組p[]並將其賦值為hello world(數組的空間大小為12),2返回數組名p付給str指標(即返回了數組的首地址).那麼這樣就可以列印出字串"hello world"了嗎?當然是不能的!因為在函數調用的時候漏掉了最後一步.也就是在第2步return數組名後,函數調用還要進行一步操作,也就是釋放記憶體空間.當一個函數被調用結束後它會釋放掉它裡面所有的變數所佔用的空間.所以數組空間被釋放掉了,也就是說str所指向的內容將不確定是什麼東西.
char *GetMemory(void)
{
   char p[] = "hello world";
   return p;
}

void Test(void)
{
   char *str = NULL;
   str = GetMemory();
   printf(str);
}

//NO.3:問題同NO.1,正確答案為可以列印出hello.但記憶體流失了!
void GetMemory(char **p, int num)
{
   *p = (char*)malloc(num);
}

void Test(void)
{
   char *str = NULL;
   GetMemory(&str, 100);
   strcpy(str, "hello");
   printf(str);
}

//NO.4:申請空間,拷貝字串,釋放空間.前三步操作都沒有任何問題.到if語句裡的判斷條件開始出錯了,因為一個指標被釋放之後其內容並不是NULL,而是一個不確定的值.所以if語句永遠都不能被執行.這也是著名的"野"指標問題.所以我們在編寫程式釋放一個指標之後一定要人為的將指標付成NULL.這樣就會避免出現"野"指標的出現.有人說"野"指標很可怕,會帶來意想不到的錯誤.
void Test(void)
{
   char *str = (char*)malloc(100);
   strcpy(str, "hello");
   free(str);
   if (str != NULL)
   {
      strcpy(str, "world");
     printf(str);
   }
}

void GetMemory1(char *p)
{
    p = (char *)malloc(100);
}

void Test1(void)
{
    char *str = NULL;
    GetMemory1(str);
    strcpy(str, "hello world");
    printf(str);
}
//str一直是空,程式崩潰
char *GetMemory2(void)
{
    char p[] = "hello world";
    return p;
}
void Test2(void)
{
    char *str = NULL;
    str = GetMemory2();
    printf(str);
}
char *GetMemory3(void)
{
     return "hello world";
}
void Test3(void)
{
    char *str = NULL;
    str = GetMemory3();
    printf(str);
}

//Test3 中列印hello world,因為返回常量區,而且並沒有被修改過。Test2中不一定能列印出hello world,因為指向的是棧。

void GetMemory4(char **p, int num)
{
    *p = (char *)malloc(num);
}
void Test4(void)
{
    char *str = NULL;
    GetMemory3(&str, 100);
    strcpy(str, "hello");
    printf(str);
}
//記憶體沒釋放

void Test5(void)
{
    char *str = (char *) malloc(100);
    strcpy(str, "hello");
    free(str);
    if(str != NULL)
{
   strcpy(str, "world");
   printf(str);
}
}
//str為野指標,列印的結果不得而知

void Test6()
{
    char *str=(char *)malloc(100);
    strcpy(str, "hello");
    str+=6;
    free(str);
    if(str!=NULL)
    {
        strcpy(str, "world");
        printf(str);
    }
}
//VC宣告失敗,運行錯誤

//NO.1:程式首先申請一個char類型的指標str,並把str指向NULL(即str裡存的是NULL的地址,*str為NULL中的值為0),調用函數的過程中做了如下動作:1申請一個char 類型的指標p,2把str的內容copy到了p裡(這是參數傳遞過程中系統所做的),3為p指標申請了100個空間,4返回Test函數.最後程式把字串hello
world拷貝到str指向的記憶體空間裡.到這裡錯誤出現了!str的空間始終為NULL而並沒有實際的空間.深刻理解函數調用的第2步,將不難發現問題所在!
void GetMemory(char *p)
{
   p = (char*)malloc(100);
}

void Test(void)
{
   char *str = NULL;
   GetMemory(str);
   strcpy(str, "hello world");
   printf(str);
}
//請問運行Test函數後會是什麼樣的結果?

//NO.2:程式首先申請一個char類型的指標str,並把str指向NULL.調用函數的過程中做了如下動作:1申請一數組p[]並將其賦值為hello world(數組的空間大小為12),2返回數組名p付給str指標(即返回了數組的首地址).那麼這樣就可以列印出字串"hello world"了嗎?當然是不能的!因為在函數調用的時候漏掉了最後一步.也就是在第2步return數組名後,函數調用還要進行一步操作,也就是釋放記憶體空間.當一個函數被調用結束後它會釋放掉它裡面所有的變數所佔用的空間.所以數組空間被釋放掉了,也就是說str所指向的內容將不確定是什麼東西.
char *GetMemory(void)
{
   char p[] = "hello world";
   return p;
}

void Test(void)
{
   char *str = NULL;
   str = GetMemory();
   printf(str);
}

//NO.3:問題同NO.1,正確答案為可以列印出hello.但記憶體流失了!
void GetMemory(char **p, int num)
{
   *p = (char*)malloc(num);
}

void Test(void)
{
   char *str = NULL;
   GetMemory(&str, 100);
   strcpy(str, "hello");
   printf(str);
}

//NO.4:申請空間,拷貝字串,釋放空間.前三步操作都沒有任何問題.到if語句裡的判斷條件開始出錯了,因為一個指標被釋放之後其內容並不是NULL,而是一個不確定的值.所以if語句永遠都不能被執行.這也是著名的"野"指標問題.所以我們在編寫程式釋放一個指標之後一定要人為的將指標付成NULL.這樣就會避免出現"野"指標的出現.有人說"野"指標很可怕,會帶來意想不到的錯誤.
void Test(void)
{
   char *str = (char*)malloc(100);
   strcpy(str, "hello");
   free(str);
   if (str != NULL)
   {
      strcpy(str, "world");
     printf(str);
   }
}

void GetMemory1(char *p)
{
    p = (char *)malloc(100);
}

void Test1(void)
{
    char *str = NULL;
    GetMemory1(str);
    strcpy(str, "hello world");
    printf(str);
}
//str一直是空,程式崩潰
char *GetMemory2(void)
{
    char p[] = "hello world";
    return p;
}
void Test2(void)
{
    char *str = NULL;
    str = GetMemory2();
    printf(str);
}
char *GetMemory3(void)
{
     return "hello world";
}
void Test3(void)
{
    char *str = NULL;
    str = GetMemory3();
    printf(str);
}

//Test3 中列印hello world,因為返回常量區,而且並沒有被修改過。Test2中不一定能列印出hello world,因為指向的是棧。

void GetMemory4(char **p, int num)
{
    *p = (char *)malloc(num);
}
void Test4(void)
{
    char *str = NULL;
    GetMemory3(&str, 100);
    strcpy(str, "hello");
    printf(str);
}
//記憶體沒釋放

void Test5(void)
{
    char *str = (char *) malloc(100);
    strcpy(str, "hello");
    free(str);
    if(str != NULL)
{
   strcpy(str, "world");
   printf(str);
}
}
//str為野指標,列印的結果不得而知

void Test6()
{
    char *str=(char *)malloc(100);
    strcpy(str, "hello");
    str+=6;
    free(str);
    if(str!=NULL)
    {
        strcpy(str, "world");
        printf(str);
    }
}
//VC宣告失敗,運行錯誤

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.