2

새로운 것을 사용하여 동적으로 할당 한 2 차원 배열이 있습니다.새로운 메모리 블록을 어떻게 할당합니까?

문제는 처리 속도를 높이기 위해 분리 된 조각 대신 하나의 연결된 블록으로 메모리를 할당하려고합니다.

새로운 기능으로 이것을 수행 할 수 있는지 알 수 있습니까? 아니면 malloc을 사용해야합니까? 여기

내 코드 : 당신은 new 함께 할 수 없어 당신이 malloc과 함께 할 수있는 일은이 (없다

A = new double*[m]; 
    for (int i=0;i<m;i++) 
    { 
     A[i]= new double[n]; 
    } 

이 코드 세그먼트 오류

phi = new double**[xlength]; 
phi[0] = new double*[xlength*ylength]; 
phi[0][0] = new double[xlength*ylength*tlength]; 
for (int i=0;i<xlength;i++) 
{ 
    for (int j=0;j<ylength;j++) 
    { 
     phi[i][j] = phi[0][0] + (ylength*i+j)*tlength; 
    } 
    phi[i] = phi[0] + ylength*i; 
} 
+0

1D 배열로 2D 연산을 나타내는'Matrix' 클래스를 만드는 것이 좋습니다. – chris

+0

http://stackoverflow.com/questions/1719607/is-the-memory-allocated-by-new-operated-consecutive보세요. – Bill

+0

@bill, 그건 내 질문에 대답하지 않았지만 링크를 주셔서 감사합니다. – Mechy

답변

3

을해야합니다 :

double* A = new double[m*n]; 
for (int i=0; i<m; i++) { 
    for (int j=0; j<n; j++) { 
     A[i*n+j] = <my_value>; 
    } 
} 

을 대신 new를 사용하여, 당신은 사용할 수 있습니다 malloc - 으로 new을 출시해야하고, free()으로 풀어 놓은 malloc()을 제외하고 별 차이가 없습니다.

갱신 1 : 다음과 같이 "true"로 2 차원 배열을 만들 수 있습니다

double** A = new double*[m]; 
double* B = new double[m*n]; 
for (int i=0; i<m; i++) { 
    A[i] = B + n*i; 
} 
for (int i=0; i<m; i++) { 
    for (int j=0; j<n; j++) { 
     A[i][j] = <my_value>; 
    } 
} 

그냥 결국 모두 AB을 해제해야합니다.

UPDATE2 :

double*** A = new double**[m]; 
double** B = new double*[m*n]; 
double* C = new double[m*n*o]; 
for (int i=0; i<m; i++) { 
    for (int j=0; j<n; j++) { 
     B[n*i+j] = C + (n*i+j)*o; 
    } 
    A[i] = B + n*i; 
} 
for (int i=0; i<m; i++) { 
    for (int j=0; j<n; j++) { 
     for (int k=0; k<o; k++) { 
      A[i][j][k] = <my_value>; 
     } 
    } 
} 

이 2 비교적 사용 인기 요청에 의해

이하면 (치수 m X n X o으로) "true"를 3 차원 배열을 만드는 방법이다 작은 "인덱스"배열 AB 및 데이터 배열 C. 평소와 같이, 세 가지 모두 사용 후 해제해야합니다.

자세한 내용은이 항목을 확장하여 독자의 연습 문제로 남겨 두십시오.

+0

이것은 1 차원 배열을 만드는 좋은 방법이지만 배열을 평탄화하지 않으려면 malloc과 같이 새로운 메모리 블록을 만들 수 있습니까? – Mechy

+0

@Mechy, 만약 내가 미쳤다면 이것에 관해서는 인용하지 말아라. 그러나 만일 당신이 공간의 20 %를 새로 만들었다면, 그것과 같은 포인터를 처리하는 것으로 도망 갈 수있을 것이다. 'int [4] [5]'또는'int [5] [4]'로 시작합니다. 그게 허용되는지 확실하지 않습니다. 어쨌든'Matrix' 클래스로 캡슐화하면 훨씬 더 깨끗합니다. 'mat (i, j)'라고 말할 수는 있지만 내부적으로 1D 연속 덩어리가되어야합니다. – chris

+0

@Mechy : 예, 할 수 있습니다 - 업데이트 된 답변보기 – mvp

0

의 원인이되는 반대하지만 보유하지 않음). 그러나 이미 별도의 블록에 메모리를 할당 한 경우 연결 블록 (malloc 또는 new)을 가져 오기 위해 새로운 (인접한) 메모리를 할당해야합니다. 표시된 코드는 m 비 연속적인 n 크기 블록을 할당합니다. 이에서 연속 메모리 배열을 얻으려면, 당신은 이런 식으로 뭔가를 하나 개의 큰 블록을 할당하고 적절하게 사용할 수 있습니다

int MN = m*n; 
B = new double[MN]; 
for (int i=0; i<MN; ++i) 
    B[i] = A[ i/N ] [ i%N ]; 
+0

그것이 이미 하나의 큰 메모리 블록이라는 것을 의미합니까? 나는 그 물건이 다른 위치에 스트립을 할당 할 것이라고 생각했다. 예를 들어 A <- 여기 스트립 A ------------------------> 스트립 B는 A의 오른쪽 대신에 여기에 있습니다. – Mechy

+0

@Mechy , 네가 옳아. 그것은 들쭉날쭉 한 배열입니다. – chris

+0

어떻게 해결할 수 있습니까? 나는 그것들을 들쭉날쭉하게 만들고 싶지 않다. – Mechy

0

좋아요, 작업이 단일 메모리 블록을 유지하면서 주소 지정 방법을 [] [] 유지하는 경우 클래스를 사용하여 몇 가지 트릭을 시도해 보겠습니다. 이 시간 절약 아니지만, 매우 효율적인 메모리가,

class CoordProxy 
{ 
private: 
    int coordX; 
    int arrayWidth; 
    int * dataArray; 

public: 
    CoordProxy(int * newArray, int newArrayWidth, int newCoordX) 
    { 
     coordX = newCoordX; 
     arrayWidth = newArrayWidth; 
     dataArray = newArray; 
    } 

    int & operator [](int newCoordY) 
    { 
     return (dataArray[newCoordY * arrayWidth + coordX]); 
    } 
}; 

class CoordsWrapper 
{ 
private: 
    int * dataArray; 
    int width; 
    int height; 

public: 
    CoordsWrapper(int * newArray, int newWidth, int newHeight) 
    { 
     dataArray = newArray; 
     width = newWidth; 
     height = newHeight; 
    } 

    CoordProxy operator[] (int coordX) 
    { 
     return CoordProxy(dataArray, width, coordX); 
    } 
}; 

int main(int argc, char * argv[]) 
{ 
    int * a = new int[4 * 4]; 
    ZeroMemory(a, 4 * 4 * sizeof(int)); 

    CoordsWrapper w(a, 4, 4); 

    w[0][0] = 10; 
    w[0][1] = 20; 
    w[3][3] = 30; 

    std::for_each(&a[0], &a[4 * 4], [](int x) { printf("%d ", x); }); 

    delete[] a; 
} 

주 : 4 개의 int 원래 2 이상의 클래스 포인터를 사용하여 첫 번째 내부 프록시이다.

도 좋네요 훨씬 빨리 해결 방법이 있습니다,하지만 당신은 (,) 표기법에 찬성 표기 [] []에서 사임해야 할 것입니다 :

class CoordsWrapper2 
{ 
private: 
    int * data; 
    int width; 
    int height; 

public: 
    CoordsWrapper2(int * newData, int newWidth, int newHeight) 
    { 
     data = newData; 
     width = newWidth; 
     height = newHeight; 
    } 

    inline int & Data(int x, int y) 
    { 
     return data[y * width + x]; 
    } 
}; 

int main(int argc, char * argv[]) 
{ 
    int * a = new int[4 * 4]; 
    ZeroMemory(a, 4 * 4 * sizeof(int)); 

    CoordsWrapper2 w(a, 4, 4); 

    w.Data(0, 0) = 10; 
    w.Data(0, 1) = 20; 
    w.Data(3, 3) = 30; 

    std::for_each(&a[0], &a[4 * 4], [](int x) { printf("%d ", x); }); 

    delete[] a; 
} 

참고 인라인 지시어. 컴파일러는 메소드 호출을 실제 소스 코드로 대체 할 것을 제안합니다. 이 솔루션은 훨씬 더 효율적이며 고전적인 인덱싱만큼 효율적이지 않으며 시간이 절약됩니다.

관련 문제