2012-01-24 5 views
0

값과 참조를 사용하여 함수에 포인터를 전달하는 것의 차이점을 이해하려고합니다. 필자의 경우, 전달 된 포인터를 삭제하고있다. 나는 그 포인터를 삭제하는 것이 그 포인터의 수정 형태라고 가정하고있다. 따라서 배열에 대한 포인터 (ptr)를 값으로 함수에 전달하면 해당 함수 내부에서 '[] [] ptr'을 삭제해서는 안됩니다. 그러나이 방법을 사용하여 코드를 작성할 때 (ptr을 값과 참조로 전달하는 경우) 컴파일러에서 두 가지 경우 모두 함수 내에서 ptr을 삭제할 수 있습니다.값에 의한 함수 포인터와 참조에 의한 포인터 간의 차이점

값으로 전달 된 포인터를 삭제할 수 없다고 생각해서 혼란 스럽습니다. 나는 아래에 간단한 코드를 추가하고있다. 스택 오버플로에 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 컵에 불과하므로 식용 색을 추가하는 것과 같은 컵의 변경은 해당 컵을 사용하는 모든 것에 발생합니다. 그러나 가치에 의한 합격은 동일한 두 번째 컵을 만드는 것과 같습니다.하지만 컵에 식용 색소를 추가하면 원래 컵은 분명합니다.

참조로 전달할 때 호출 함수로 반환하지 않고 메모리의 객체에 영향을 주려는 것이 일반적입니다. 값으로 전달하면 이전 함수로 리턴하고 이전 오브젝트를 쓰는 것입니다.

더 잘 이해하는 데 도움이됩니까?

+0

종류입니다. 이 경우에도 "값"으로 포인터를 전달하면 원래 포인터의 위치를 ​​가리키는 다른 포인터가 만들어지기 때문에 두 개의 컵이 있다고 생각했습니다. 그러나 그렇지 않습니다. 값으로 포인터를 전달하는 것은 사본을 생성하지 않는 것 같습니다. – RDK

관련 문제