c++值傳遞和引用及指針傳遞區別

如下程序各有何問題?
ios

***********************************************************************************************************************************
c++

1.程序員

 

void getmemory(char*p)面試

{
p=(char *) malloc(100);
編程

}函數

int main()spa

{操作系統

char *str=NULL;
getmemory(str);
指針

strcpy(str,「helloworld」);對象

printf("%s\n",str);

}

 

首先先回顧值傳遞與指針傳遞,引用傳遞的區別:

#include <iostream.h>
void swap(int x,int y)
{
    int temp;
    temp=x;
    x=y;
    y=temp;
}

void swap(int *x,int *y)

{
    int temp;
    temp=*x;
    *x=*y;
    *y=temp;
}

void swap(int& x,int& y)
{
    int temp ;
    temp=x;
    x=y;
    y=temp;
}
void main()
{
    int x=5; int y=6;
    swap(x,y);         

  *****5,6;值傳遞是在函數做用域中創建變量或對象的副本,一旦函數結束副本消失,不影響原值;

  /*swap(&x,&y);*/

******6,5;指針傳遞傳遞的是變量或對象的地址,是在對變量或對象的原值進行操做,會改變原值;

  /*swap(x,y);*/  

*******6,5;引用傳遞形式如值傳遞但效果同指針傳遞,是原來變量或對象的別名,是在對變量或對象的原值進行操做

    cout<<「交換後:x=」<<x;
    cout<<「y=」<<y<<endl;
}

題1就如同是值傳遞,對原值str不起任何影響,str 依舊是NULL,每運行一次就有一塊內存泄露,因此當函數的參數是一個指針,不要期望用該指針去申請動態內存。

 

*********************************************************************************************************************************

 

2.

void getmemory(char*p)

{
p=(char *) malloc(100);
strcpy(p,「helloworld」);
}
int  main( )
{
char *str=NULL;
getmemory(str);
printf(「%s/n」,str);
free(str);
return 0;

}

有題1 可知道,str最終沒有分配到內存,free(str)是危險操做;

************************************************************************************************************************************

3.

 

void *getmemory(void)

{
char p[]="hello";

return p;

}

int main()

{

char *str=NULL;
str=getmemory();

printf("%s\n",str);

}

不要用return 語句返回指向「棧內存」的指針,由於該內存在函數結束時自動釋放,str指向的地址原先內容不可知,現有內容不清楚,輸出亂碼

注意:函數的返回值是指針類型的,檢查是靜態內存指針仍是堆內存指針仍是棧內存指針,棧內存指針是絕對要不得滴

************************************************************************************************************************************

4.

void  getmemory(char** p,int num)

{
*p=(char*)malloc(num);

}

int main()

{

char *str=NULL;
getmemory(&str,100);

strcpy(str,「helloworld」);

printf("%s\n",str);

}

用指向指針的指針(二級指針)申請動態內存,(c中經常使用的指針傳遞)該函數能正常輸出helloworld,可是忘記free()會形成內存泄露;

注意:(指針傳遞,一級指針)函數中只能對指針的指向的值(*p)進行修改,

         而不能修改指針地址(改變p值,*p不變)!

例:

 

void fun(int *p)

{

  int b=100;

  p=&b;       //  b的地址並無被返回

}

程序4:

void fun(int *p)

{

  *p=100; // okay

}

       (函數要求修改指針參數的地址,必須使用指針的指針!(二級指針)

(那麼c++中能夠運用引用傳遞來動態申請內存void  getmemory(char*& p,int num)

 

********************************************************************************************************************************

5.

int main()

{

char* str=(char*)malloc(100);

strcpy(str,「hello」);

free(str);

if(str!=NULL)

{

strcpy(str,「world」);

printf(str);

}

return 1;

}

str 所指的內存被釋放,可是str 所指的地址仍然不變,if(str!=NULL)沒有任何做用。

str變成野指針,「野指針」不是NULL 指針,是指向「垃圾」內存的指針,

「野指針」的成因主要有兩種:
(1)指針變量沒有被初始化。任何指針變量剛被建立時不會自動成爲NULL 指針,它
的缺省值是隨機的,它會亂指一氣。因此,指針變量在建立的同時應當被初始化,要麼
將指針設置爲NULL,要麼讓它指向合法的內存。例如
char *p = NULL;
char *str = (char *) malloc(100);
(2)指針p 被free 或者delete 以後,沒有置爲NULL,讓人誤覺得p 是個合法的指針。
(3)指針操做超越了變量的做用範圍。這種狀況讓人防不勝防,示例程序以下:
class A
{
public:
void Func(void){ cout << 「Func of class A」 << endl; }
};
void Test(void)
{
A *p;

{
A a;
p = &a; // 注意 a 的生命期
}

p->Func(); // p 是「野指針」
}
函數 Test 在執行語句p->Func()時,對象a 已經消失,而p 是指向a 的,因此p 就成了「野指針」。

 

*********************************************************************************************************************************

 

內存管理

中軟面試題: 

內存有哪幾種存儲組織結構.請分別加以說明《來自高質量c/c++編程》

1.從靜態存儲區域分配:

內存在程序編譯時就已經分配,這塊內存在程序整個運行過程都存在。(全局變量,static變量)

2.在棧上建立:

函數內部的局部變量在棧上建立,函數結束後,這些存儲單元會自動釋放。 分配內存效率高,可是分配內存容量有限

3.從堆上分配(動態內存分配):

由malloc()和new()手動分配內存,由delete(),free()手動釋放內存空間。內存空間由程序員本身決定,可分配的內存容量大。

注意:

malloc申請的是連續的一塊內存,當返回NULL表示內存申請失敗,用if(NULL!=p)驗證, 如果內存分配失敗用exit(1),終止整個程序; 棧出現內存泄露狀況一般是由沒有回收垃圾資源,沒有進行內存釋放引發的

 free(p);斬斷了指針與這塊內存的關係,

          雖然指針P仍然保存原來的地址,可是已經失去了對那塊內存的控制權,一樣,對應的那塊內存雖然內容存在,不過,已經沒法利用其中的數據,成爲垃圾文件對於每次malloc()只能有一次free(),若free()兩次會出錯,除非原指針指向NULL

全局變量和局部變量有什麼區別?是怎麼實現的?操做系統和編譯器是怎麼知道的?

生命週期不一樣:全局變量隨主程序建立和建立,隨主程序銷燬而銷燬;局部變量在局部函數內部,甚至局部循環體等內部存在,退出就不存在;內存中分配在全局數據區。

使用方式不一樣:經過聲明後全局變量程序的各個部分均可以用到;局部變量只能在局部使用;分配在棧區。
操做系統和編譯器經過內存分配的位置來知道的,

全局變量分配在全局數據段而且在程序開始運行的時候被加載。局部變量則分配在堆棧裏面。

                                                       fmoonstar 更新至2011.11.4

相關文章
相關標籤/搜索