7

Tôi gặp sự cố với dự án. Tôi phải tạo một mảng 2D có kích thước thay đổi để lưu trữ một số lỗi dự đoán .. đây là hình ảnh. Vấn đề là tôi phải tải hình ảnh có kích thước khác nhau cho mỗi hình ảnh tôi sẽ phải nhận được vào một tập tin các mảng 2D với số lượng lõi pixel .. Tôi đã tìm kiếm trong số các câu hỏi của bạn nhưng nó không phải là những gì tôi đang tìm kiếm for.Có ai giúp tôi không?Làm thế nào để khai báo một mảng 2D có kích thước thay đổi trong C?

Cảm ơn bạn

Trả lời

0

Bạn cần cấp phát bộ nhớ động. Sử dụng logic con trỏ kép.

Ex:

int n=10; <<-u can change this. 
int **a; 
a=(int **)malloc(sizeof(*int)*n); 
for (int i=0;i<n;i++){ 
a[i]=(int *)malloc(sizeof(int)*n);// or *(a+i) 
} 
+1

Không có con trỏ kép nào không phải là mảng đa chiều. –

+0

Chắc chắn không, nhưng bạn có thể làm cho nó hoạt động giống như một mảng – Akshay

+0

Tại sao sử dụng mô phỏng một mảng 2D khi bạn chỉ đơn giản là có thể sử dụng một mảng? –

6

Nếu bạn có một trình biên dịch C hiện đại (ít nhất là C99) trong phạm vi chức năng nó cũng đơn giản như:

unsigned arr[n][m]; 

này được gọi là mảng chiều dài thay đổi (VLA). Nó có thể có vấn đề nếu mảng quá lớn. Vì vậy, nếu bạn có hình ảnh lớn, bạn có thể làm:

unsigned (*arr)[m] = malloc(sizeof(unsigned[n][m])); 

và sau

free(arr); 
+0

Hãy nhớ rằng mảng độ dài biến được đề cập ở trên sẽ được cấp phát trên ngăn xếp. Điều thứ hai không liên quan đến câu hỏi là C++ 0X không hỗ trợ tính năng này (tuy nhiên vì đây là câu hỏi C nên hoạt động tốt) – Yavar

+0

@Yavar, đó là lý do tại sao tôi cũng đề cập đến phiên bản được phân bổ bằng 'malloc' . Và thậm chí sau đó nó là một "loại biến đổi". Và C++ rõ ràng có những cách khác để làm các mảng đa chiều, vì vậy có, điều này không liên quan chút nào. –

0

Đối với một ví dụ nếu bạn xem xét phân bổ một mảng 2D int:

int **array1 = (int**) malloc (nrows *sizeof(int*)); 

for (int i=0; i<nrows;i++) 
    array1[i]=(int*) malloc (ncols *sizeof(int)); 

nơi nrows -> không of rows ncols -> không có cột nào là const hoặC# define's

2

Nếu bạn cần bộ nhớ tiếp giáp, bạn có một vài lựa chọn.

Bạn năng động có thể phân bổ một khối duy nhất của bộ nhớ, và sau đó tính toán offsets của bạn bằng tay, như vậy:

size_t rows, cols; 
... 
int *arr = malloc(sizeof *arr * rows * cols); 
... 
arr[i * rows + j] = ...; // logically equivalent to arr[i][j] 

Bạn có thể thiết lập một mảng thứ hai của con trỏ vào mảng chính:

int **arrp = malloc(sizeof *arrp * rows); 
... 
for (i = 0; i < rows; i++) 
    arrp[i] = &arr[i * rows]; 
... 
arrp[i][j] = ...; 

nhớ rằng bạn sẽ phải miễn phí cả haiarrarrp.

Nếu bạn có một thực hiện C99, bạn chỉ có thể thiết lập một con trỏ đến một VLA, như vậy:

int (*arrp)[cols] = (int (*)[cols]) arr; 
... 
arrp[i][j] = ...; 

Lưu ý rằng trong trường hợp này, bạn không bố trí bất kỳ bộ nhớ cho một mảng thứ cấp, bạn cũng không cần phải tính toán con trỏ theo cách thủ công vào mảng chính; tất cả những gì bạn phải làm là đặt arrp đến cùng một vị trí như arr và để cho các quy tắc về số học con trỏ thực hiện tất cả công việc.

Nếu những hình ảnh không phải là lớn, bạn chỉ có thể thiết lập một VLA (một lần nữa, C99 hoặc mới hơn):

int arr[rows][cols]; 

nhưng trong thực tế đây không phải là một ý tưởng tốt; stack frame thường có kích thước khá giới hạn.

+0

Trong trường hợp thứ ba của bạn, tôi nghĩ rằng việc phân bổ được thực hiện tốt hơn như tôi đã cho nó trong câu trả lời của tôi. Chỉ cần 'malloc' trực tiếp, không cần phải đúc, điều này chỉ làm xáo trộn. –

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