2011-02-18 6 views
1

일부 고정 배열뿐만 아니라 일부 동적 할당 배열을 사용하는 C++ 클래스를 작성했습니다. 만약 누군가가 동적 배열을위한 메모리를 할당하는 올바른 방법을 안내해 줄 수 있는지, 아마도 constructor/deconstructor에서, 그리고 명시 적으로 호출하여 seg fault가 발생하지 않도록해야하는지 궁금합니다. 그래서 여기C++ 클래스의 2D 배열에 대한 적절한 메모리 할당

class Network { 

    public: 
    int n_nodes; 
    int user_index[MAX_USERS]; //a fixed array 
    int adjacency_matrix[][MAX_ITEMS]; 

    //Network(int n_node, int** adjacency); //I would rather to set the element s in a function other than the constructor 
    Initializer(int n_node, int** adjacency); 
    ~Netowrk(); 
    } 

이 클래스 내 특정 질문은 다음과 같습니다 : 여기 내 코드의 관련 부분의 단순화 된 버전입니다

1 - 나는 [] [] 미정와 2 차원 배열 adjacency_matrix을 가질 수 이니셜 라이저 함수에서 사용자가 설정할 때까지 행과 열 수?

2 - 2D 배열은 어디에서 삭제해야합니까? 나는 그것을 deconstructor에 써야합니까? 나는 deconstructor를 명시 적으로 호출해야합니까? 디스트 리뷰 터에서 파괴해야 할 것이 있습니까?

+0

Dupe? http://stackoverflow.com/questions/2294338/c-2d-dynamic-array –

답변

2

1 - 이니셜 라이저 기능에서 사용자가 설정하기 전까지 결정되지 않은 수의 행과 열로 구성된2D 배열을 가질 수 있습니까?

예. 그러나이를 수행하는 가장 좋은 방법은 배열을 전혀 사용하지 않는 것입니다. 대신, 메모리를 관리하는 std::vector을 사용하십시오. 당신이 이것을 할 수있는 두 가지 방법이 있습니다. 당신이 실제로 요소에 액세스 할 수 [row][column] 구문을 사용할 수 있도록하려면, 당신은 std::vector의 두 개의 차원을 사용해야합니다 : 당신이 치수를 알고 있으면

std::vector<std::vector<int> > adjacency_matrix; 

, 당신은 그것을 채울 수 있습니다 :

adjacency_matrix.assign(rows, std::vector<int>(columns)); 

모든 요소가 포함 된 1 차원 배열 (또는 std::vector<int>)을 사용하고 을 사용하여 인덱스 (row, column)의 요소에 액세스하는 것이 더 쉽습니다. 이렇게하면 동적 할당이 줄어 듭니다. 요소에 액세스하는 논리를 몇 가지 도우미 함수로 마무리 할 수 ​​있습니다.

2 - 2D 배열은 어디에서 삭제해야합니까? 나는 그것을 deconstructor에 써야합니까?

std::vector을 사용하는 경우에는 delete의 어떤 것도 필요하지 않습니다. 그것은 스스로를 깨끗이합니다.

[소멸자]를 명시 적으로 호출해야합니까? 나는 [소멸자]에 파괴 할 필요가 무엇을

번호

있습니까?

이상적으로 아니오. std::vector과 스마트 포인터 같은 표준 라이브러리 컨테이너를 사용하는 경우에는 아무 것도 정리하지 않아도됩니다. C++에서 직접 리소스를 관리하지 않아야합니다. 지루한 작업을 수행 할 수있는 라이브러리 기능이 있으므로이를 활용해야합니다.

0

1 - 이니셜 라이저 기능에서 사용자가 설정하기 전까지 결정되지 않은 수의 행과 열이있는 2D 배열 adjacency_matrix [] []를 가질 수 있습니까?

예 너 수 있습니다.입니다. 예를 들면 :

int* adjacency_matrix_; 
    int* getAdjacency(int i, int j) 
    { 
     if (!adjacency_matrix_) 
      return 0; 
     else 
      return adjacency_matrix_ + i*n_nodes + j; 
    } 
    Network() 
     : n_nodes(0), 
     adjacency_matrix_(0) 
    {} 
    void Initializer(int n_node, int** adjacency) 
    { 
     adjacency_matrix_ = new int[n_nodes * n_nodes]; 
     // Copy over data. 
    } 

에 관해서는 당신이 std::vector<>를 사용하지 않는 이유가 있는지 여부에 따라 달라 해야 여부.

2 - 2D 배열은 어디에서 삭제해야합니까? 나는 그것을 deconstructor에 써야합니까? deconstructor를 명시 적으로 호출해야합니까? 디 컴포지션에서 파괴해야 할 것이 있습니까?

, 삭제 소멸자를 사용하여 배열을 운영자에 확실히 무료 :

~Network() 
    { 
     delete [] adjacency_matrix_; 
    } 

네트워크 개체 자체가 범위를 벗어나마다 아니, 당신의 소멸자가 호출됩니다. 명시 적 소멸자 호출을하는 것은 거의 필요하지 않습니다.

아니요, 소멸자가 명시 적으로 해제해야하는 모든 것은 명시 적으로 획득 한 것입니다.

0

당신은 내가 an answer to another question

자체가 좋은 C++ 설계 관행에 대해이었다 질문에 쓴 예 행렬 클래스를 같은 수 있지만, 선택한 예는 다차원 배열했다.

0

이렇게하는 방법에는 여러 가지가 있습니다.

가장 쉬운 방법은 벡터를 사용하는 것입니다. 자신의 메모리를 관리하고 싶지 않다면 이것이 가장 적합합니다. 그러나 나는 내 자신의 기억을 관리하기를 좋아하고, 때때로이 방법이 느리고 성가시다는 것을 알았 기 때문에 다른 방법을 배웠다.

가장 빠른 방법은 1 차원 배열을 할당하고 2 차원 배열처럼 처리하는 것입니다.

이는 n 번째 차원으로 일반화 될 수
int *array = new int[width*height]; 

int get_array(int column, int row) 
{ 
    return array[row*width + column]; 
} 

delete [] array; 

: 각 행에 대해 서로 다른 폭을 가질 수 있도록하려면

int *array = new int[w1*w2*...*wn]; 

int get_array(int i1, int i2, ..., int in) 
{ 
    return array[in*(w1*w2*...*w(n-1)) + i(n-1)*(w1*w2*...*w(n-2)) + ... + i2*w1 + i1]; 
} 

delete [] array; 

는, 다음의 배열을 만들 수 있습니다 여기에 예입니다 포인터. 이 솔루션은 초기화 및 정리가 느리지 만 유연하지만 조정 가능하며 실행 시간이 비교적 빠릅니다. 실수로 실수를하는 경우에도 매우 위험 할 수 있습니다.

int **array = new int*[height]; 

for (int i = 0; i < height; i++) 
    array[i] = new int[width(i)]; 

하는 시점에서, 액세스 할, 당신이 할 일은 당신이 행에 의해 행해야 할이 배열을 무료로, 그러나 관습

array[i][j] 

입니다

for (int i = 0; i < height; i++) 
    delete [] array[i]; 

delete [] array; 

이것은 또한 n 번째 차원으로 일반화 할 수 있습니다.

int **....*array = new int**...*[w1]; 

for (int i1 = 0; i1 < w1; i1++) 
{ 
    array[i1] = new int**..*[w2]; 
    for (int i2 = 0; i2 < w2; i2++) 
    { 
      array[i1][i2] = new int**.*[w3]; 
      ... 
      for (int in = 0; in < wn; in++) 
       array[i1][i2]...[in] = new int[wn]; 
    } 
} 

for (int i1 = 0; i1 < w1; i1++) 
{ 
    for (int i2 = 0; i2 < w2; i2++) 
    { 
      ... 
      for (int in = 0; in < wn; in++) 
       delete [] array[i1][i2]...[in]; 
      ... 
      delete [] array[i1][i2]; 
    } 
    delete [] array[i1]; 
} 

delete [] array; 

이러한 종류의 설정은 메모리에 혼란을 야기하는 경향이 있습니다. 이들의 단지 2 차원 배열은 malloc 될 폭 + 1 개의 분리 된 배열이됩니다. 하나의 큰 배열을 malloc하여 색인을 직접 찾아내는 것이 더 빠를 것입니다.