2013-08-16 74 views
21

Tôi đã gặp may mắn với các con trỏ động khi tôi đưa chúng đến 2 kích thước và cao hơn. Ví dụ tôi muốn một con trỏ đến một mảng 2D. Tôi biết rằng:Cách chính xác để khởi tạo một con trỏ động tới một mảng đa chiều?

int A[3][4]; 
int (*P)[4] = A; 

Hoàn toàn hợp pháp (ngay cả khi tôi không hiểu rõ lý do). Cân nhắc rằng:

int *P = new int[4]; 

tác phẩm, tôi tưởng tượng rằng:

int **P = new int[5][7]; 

cũng sẽ làm việc, nhưng nó không phải. Mã này khẳng định lỗi:

Error: A value of type "(*)[7]" cannot be used to initialize an entity of 
     type "int **" 

Bằng nhìn thấy điều này phần mới trở thành một con trỏ đến một mảng của 7 số nguyên tôi đã thực hiện:

int (*P)[4] = new int[7][4]; 

Và điều này không làm việc nhưng nó không phải là những gì tôi muốn đạt được . Bằng cách làm như thế tôi bị giới hạn ít nhất bằng cách sử dụng một giá trị không đổi cho bất kỳ thứ nguyên tiếp theo nào, nhưng tôi muốn nó được định nghĩa đầy đủ vào thời gian chạy và do đó "động".

Làm cách nào tôi có thể thực hiện và làm cho con trỏ đa chiều này hoạt động?

+1

Đừng quên xóa chúng – doctorlove

+0

'std :: vector > ' – Chad

Trả lời

53

Hãy bắt đầu với một số ví dụ cơ bản.

Khi bạn nói int *P = new int[4];

  1. new int[4]; cuộc gọi hàm operator mới()
  2. phân bổ một bộ nhớ cho 4 số nguyên.
  3. trả về tham chiếu đến bộ nhớ này.
  4. để ràng buộc thông tin này, bạn cần phải có cùng một loại con trỏ như tham chiếu trở lại, do đó bạn làm

    int *P = new int[4]; // As you created an array of integer 
            // you should assign it to a pointer-to-integer 
    

Đối với một mảng đa idimensional, bạn cần phải phân bổ một mảng của con trỏ , sau đó điền rằng mảng với con trỏ đến mảng, như thế này:

int **p; 
p = new int*[5]; // dynamic `array (size 5) of pointers to int` 

for (int i = 0; i < 5; ++i) { 
    p[i] = new int[10]; 
    // each i-th pointer is now pointing to dynamic array (size 10) 
    // of actual int values 
} 

đây là những gì nó trông giống như:

enter image description here

Để giải phóng bộ nhớ

  1. Đối với một mảng chiều,

    // need to use the delete[] operator because we used the new[] operator 
    delete[] p; //free memory pointed by p;` 
    
  2. Đối 2d Array,

    // need to use the delete[] operator because we used the new[] operator 
    for(int i = 0; i < 5; ++i){ 
        delete[] p[i];//deletes an inner array of integer; 
    } 
    
    delete[] p; //delete pointer holding array of pointers; 
    

Tránh mem ory rò rỉ và con trỏ lủng lẳng!

5

Bạn muốn một cái gì đó như:

int **P = new int*[7]; 
p[0] = new int[5]; 
p[1] = new int[5]; 
... 
2

cách tiếp cận khác sẽ được sử dụng một mảng 1D như một mảng 2D. Bằng cách này bạn chỉ phải cấp phát bộ nhớ một lần (một khối liên tục);

int *array; 
size_t row=5,col=5; 
array = (int*)malloc(row*col*sizeof(int)) //or new int[row*col] 

Điều này sẽ dẫn đến tương tự như "int array [5] [5]".

để truy cập các lĩnh vực mà bạn vừa làm:

array[1 //the row you want 
* col //the number of columns 
+2//the column you want 
] = 4; 

Đây là bằng:

array[1][2]; 
2

này thực hiện kiểm tra giới hạn trên một số trình biên dịch debug, sử dụng kích thước động và xóa tự động. Chữ ký chỉ có x và y là vòng đối diện.

std::vector<std::vector<int>> array2d(y_size, std::vector<int>(x_size)); 

for (int y = 0; y < y_size; y++) 
{ 
    for (int x = 0; x < x_size; y++) 
    { 
     array2d[y][x] = 0; 
    } 
} 
+1

Không nó không thực hiện kiểm tra giới hạn. –

Các vấn đề liên quan