2010-07-18 5 views
9

Tôi hiện đang cố gắng hiểu cách triển khai mảng cấu trúc 2 chiều trong C. Mã của tôi luôn gặp sự cố nó kết thúc giống như tất cả các cách tiếp cận của tôi trở nên vững chắc với C: rác. Đây là những gì tôi nhận:Cách triển khai mảng 2 chiều của cấu trúc trong C

typedef struct { 
    int i; 
} test; 

test* t[20][20]; 
*t = (test*) malloc(sizeof(test) * 20 * 20); 

lỗi vinh quang của tôi:

error: incompatible types when assigning to type ‘struct test *[20]’ from type ‘struct test *’

Tôi có phải phân bổ bộ nhớ riêng biệt cho mỗi chiều thứ 2? Tôi đang nhận hạt. Nó sẽ rất đơn giản. Một ngày nào đó tôi sẽ xây dựng một thời gian máy và từ hóa một số c-trình biên dịch bằng đĩa mềm ...

Trả lời

22

này nên là đủ:

typedef struct { 
    int i; 
} test; 

test t[20][20]; 

Đó sẽ khai báo một mảng 2 chiều của test của size 20 x 20. Không cần sử dụng malloc.

Nếu bạn muốn tự động phân bổ mảng của bạn, bạn có thể làm điều này:

// in a function of course 
test **t = (test **)malloc(20 * sizeof(test *)); 
for (i = 0; i < 20; ++i) 
    t[i] = (test *)malloc(20 * sizeof(test)); 
+0

Cảm ơn bạn rất nhiều! – Mortezaipo

6
test **t; 

t = (test **)malloc(sizeof(test *) * 20); 
for (i = 0; i < 20; i++) { 
    t[i] = (test *)malloc(sizeof(test) * 20); 
} 
+0

Bạn đang thiếu một 20. – IVlad

+3

cố định. Tôi ghét c. – BobTurbo

3

câu trả lời khác cho thấy làm thế nào để sửa chữa nó nhưng họ không giải thích lý do tại sao. Khi trình biên dịch gợi ý, loại t trong ví dụ ban đầu của bạn thực sự là test *[20] đó là lý do khiến dàn diễn viên của bạn bị test * không đủ.

Trong C, tên của một mảng T của thứ nguyên N thực sự thuộc loại *T[dim0][dim1]...[dimN-1]. Vui vẻ.

1

Từ quan sát của tôi, bạn có thể không biết chính xác những gì bạn muốn và gây nhầm lẫn về cấu trúc và số học con trỏ. Vui lòng trải qua 2 khả năng sau.

1) Mảng hai chiều với mỗi phần tử có con trỏ đến test. Trong trường hợp này, bộ nhớ của tất cả các con trỏ đến test s đã được static được phân bổ. Nhưng, bộ nhớ của test s thực sự chưa sẵn sàng. Trong trường hợp này, bạn phải điền vào test [i][j] từng cái một.

Mỗi một trong số test là rời rạc trong bộ nhớ và bạn có lợi thế là tạo hoặc tiêu diệt chúng một cách linh hoạt.

typedef struct { 
    int i; 
} test; 

test* t[20][20]; 
/* or instead of statically allocated the memory of all the pointers to tests 
    you can do the following to dynamically allocate the memory 
    test ***t; 
    t = (test***)malloc(sizeof(test *) * 20 * 20); 
*/ 

for (int i=0; i < 20; i++){ 
    for (int j=0; j < 20; j++){ 
     t[i][j] = malloc(sizeof(test)); 
    } 
} 

2) Mảng hai chiều với mỗi phần tử là test. Trong trường hợp này, bộ nhớ của tất cả các test s đã được phân bổ. Ngoài ra, bộ nhớ của test s thực thực sự sẵn sàng để sử dụng mà không cần chuẩn bị thêm.

Tất cả các test s liên tục trong bộ nhớ dưới dạng khối lớn và luôn ở đó. Điều này có nghĩa là bạn có thể lãng phí một đoạn bộ nhớ nếu bạn chỉ cần tất cả test s ở thời gian cao điểm nhất định và hầu hết thời gian bạn chỉ sử dụng một vài trong số chúng.

typedef struct { 
    int i; 
} test; 

test t[20][20]; 
/* or instead of statically allocated the memory of all tests 
    you can do the following to dynamically allocate the memory 
    test **t; 
    t = (test**)malloc(sizeof(test) * 20 * 20); 
*/ 
0

Ngoài ra, miễn là kích thước chiều bên trong của bạn là không đổi, bạn có thể phân bổ một số biến của tội danh mà chiều bên

int n = ...; 
test (*t)[20] = malloc(sizeof (*t) * n); 
t[0 .. (n-1)][0 .. 19] = ...;