2012-01-24 17 views
0

値と参照を使用して関数へのポインタを渡すことの違いを理解しようとしています。私の場合は、渡されたポインタを削除しています。私は、ポインタを削除すると、そのポインタの変更の一種であると仮定しています。だから、配列にポインタを渡した場合(ptr)、値を関数に渡すと、その関数の中で 'delete [] ptr'を許可してはいけません。しかし、私はこれを行う両方の方法(ptrを値だけでなく参照で渡す)をコード化すると、コンパイラはどちらの場合でも関数内でptrを削除できるようにします。値へのポインタと参照による関数へのポインタの受け渡しの違い

私は値渡しのポインタを削除できないと思っていたので混乱しています。私は以下の簡単なコードを追加しています。 Stack Overflowにはrelated questionがありましたが、OPの中には関数内のポインタを変更することに興味がなかったので、私の質問には答えません。

// Understanding passing by value and reference for pointers 

#include<iostream> 

using namespace std; 

int* createNew_value(int* _oarr, int &_size); 
// createNew_value() appends an integer to the input integer array _oarr. The 
// value of _size is incremented by one after the call to createNew_value. The 
// pointer to array _oarr is passed by value. 

int* createNew_reference(int* &_oarr, int &_size); 
// Same functionality as createNew_value(), but here the pointer to array _oarr 
// is passed by reference. 

void displayIntArray(int* _iarr,int _size); 
// Just diplays elements of the passed integer array. 

int main() 
{ 
    int *int_array; 
    int size; 

    cout << "Enter the number of elements:"; 
    cin >> size; 

    int_array = new int [size]; 

    // Initialize elements of array to consecutive integers. This initialization 
    // is only here to ensure that the elements of array are not undefined. 
    // Other than that this initialization doesnt serve any purpose 

    for (int j = 0; j <= size - 1; j++) 
     int_array[j] = j; 

    // Display the starting location and elements of the filled array;  
    cout << "[main()]: int_array [before createNew_value()] = " << int_array << endl; 
    displayIntArray(int_array,size); 

    // Display the starting location and elements of the filled array, after 
    // call to createNew_value(). 

    int_array = createNew_value(int_array, size); 

    cout << "[main()]: int_array [after createNew_value()] = " << int_array << endl; 
    displayIntArray(int_array,size); 

    // Display the starting location and elements of the filled array, after 
    // call to createNew_reference(). 

    int_array = createNew_reference(int_array, size); 

    cout << "[main()]: int_array [after createNew_reference()] = " << int_array << endl; 
    displayIntArray(int_array,size); 

    // Finally delete int_array to prevent memory leak. 
    delete [] int_array; 

    return(0); 
} 
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
int* createNew_value(int* _oarr, int &_size) 
// createNew_value() accomplishes the following: It creates a pointer to an 
// integer array, called temp, and allocates enough memory for storing (_size + 
// 1) elements. It then copies the elements of _oarr into temp, and appends one 
// more integer to temp. It then deletes the original array pointer _oarr and 
// returns temp. The return value of this function is a pointer to an array with 
// one element larger than the input array 
{ 
    int* temp; 

    temp = new int [_size + 1]; 

    //copy elements of old array, _oarr, into temp 

    for(int i = 0; i <= _size - 1; i++) 
     temp[i] = _oarr[i]; 

    temp[_size] = temp[_size - 1] + 1; 

    _size++; 

    cout << "[createNew()]: _oarr = " << _oarr << endl; 
    cout << "[createNew()]: temp = " << temp << endl; 

    delete [] _oarr; 

    // Since _oarr is passed by value, C++ SHOULDNT allow me to delete[] it !! 

    // QUESTION: I am passing _oarr by value here. So why does C++ allow me to 
    // delete [] it? Isnt deleting equivalent to modification? If yes, how can I 
    // modify _oarr if I am passing it my value? 

    return(temp); 
} 
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
int* createNew_reference(int* &_oarr, int &_size) 
// createNew_reference() accomplishes the following: It creates a pointer to an 
// integer array, called temp, and allocates enough memory for storing (_size + 
// 1) elements. It then copies the elements of _oarr into temp, and appends one 
// more integer to temp. It then deletes the original array pointer _oarr and 
// returns temp. The return value of this function is a pointer to an array with 
// one element larger than the input array 
{ 
    int* temp; 

    temp = new int [_size + 1]; 

    //copy elements of old array, _oarr, into temp 

    for(int i = 0; i <= _size - 1; i++) 
     temp[i] = _oarr[i]; 

    temp[_size] = temp[_size - 1] + 1; 

    _size++; 

    cout << "[createNew()]: _oarr = " << _oarr << endl; 
    cout << "[createNew()]: temp = " << temp << endl; 

    delete [] _oarr; 
    return(temp); 
} 

//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
void displayIntArray(int* _iarr,int _size) 
{ 
    cout << "{ "; 

    for (int n = 0; n <= _size - 2; n++) 
     cout << _iarr[n] << ", "; 

    cout << _iarr[_size - 1] << " }\n"; 
} 

答えて

1

operator deleteポインタ自体を削除しない場合は、ポインタが指すオブジェクトを削除します。したがって、オブジェクトを削除するときにすべての値を捨てることを忘れない限り、ポインタの値のコピーを好きなだけ多く作成することができます。

+0

それは明らかです。ありがとう。繰り返して言うと、ポインタp1が存在し、そのコピー 'p2 = p1'と' delete p2'を作成すると、p1とp2の両方がぶら下がります。私は正しい道にここにいますか? – RDK

+0

確かに。代わりに、あなたのために退屈なものを処理するスマートポインタの様々な種類のいずれかを使用することです。 – Neil

0

ポインタについて考えるのに最適な方法は、水のようなものです。ポインタ/参照を渡すと、1カップしか存在しませんが、そのカップを使用するものには、食べ物の色を追加するような変化が起こります。しかし、価値のあるパスは、同一の2番目の水のカップを作るようなものですが、そのカップに食用着色剤を加えると元のカップはまだクリアです。

参照渡し時に、呼び出し元の関数に返さずにメモリ内のオブジェクトに影響を与えたいというのは典型的なことです。値渡しの場合は、前の関数に戻して前のオブジェクトを上書きします。

これは理解しやすくなりますか?

+0

種類。私は、この場合でさえ2つのカップがあると考えました。 "値"によってポインタを渡すと、元のポインタの位置を指す別のポインタが作成されます。しかし、そうではありません。値でポインタを渡してもコピーは作成されないようです。 – RDK

関連する問題