01/10/2018, 08:19
Code nhập/xuất array 2d bị lỗi
E có đoạn code sau để nhập/xuất 2D array những bị lỗi khi run, nhờ mọi người giúp ạ
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void InOutArray(int ***arr, int *rows, int *columns)
{
printf("Type the number of row: ");
scanf("%d", &rows);
printf("Type the number of column: ");
scanf("%d", &columns);
*arr = (int **)calloc(*rows, sizeof(int *));
for (int i = 0; i < *rows; ++i)
(*arr)[i] = (int *)calloc(*columns, sizeof(int));
for (int i = 0; i < *rows * *columns; ++i) {
*(*((*arr) + i / *columns) + i % *columns) = 1 + rand() % 100;
printf("%4d", (*arr)[i / *columns][i % *columns]);
if ((i + 1) % *columns == 0)
printf("
");
}
}
int main()
{
srand(time(NULL));
int rows, columns;
int **arr;
InOutArray(&arr, &rows, &columns);
for (int i = 0; i < rows; ++i)
free(arr[i]);
free(arr);
return 0;
}
P/S: Do thầy bắt ko dc dùng C++ nên e ko thể dùng tham chiếu được
Bài liên quan
Sai ở đây:
&rows -> truyền vào địa chỉ của con trỏ rows.
-> tức khi bạn input 10 -> rows = 10
-> *rows = *(10) = ???
Tương tự cho column
Còn fix như thế nào thì bạn thử nghĩ xem
Ẹc, trước giờ e cứ tưởng nhập giá trị cho con trỏ dùng & vẫn dc chứ anh ?
Vậy em để
scanf("%d", rows);
vàscanf("%d", columns);
được ko anh ?Được chứ
Nhưng lúc dereference bị sai nếu ko nhập đúng địa chỉ or địa chỉ bị block ko cho truy cập -> bị lỗi lúc run-time
:)) Thử đi là biết.
E fix lại thì có vẻ là ok rồi, vậy là đúng rồi hả anh ?
Em chưa hiểu lắm @@
Tức là nhập giá trị cho con trỏ thông qua hàm thì không để & hay sao anh ?
Đúng r đó
Hàm scanf nhận vào 1 con trỏ là vì để nó gán giá trị thông qua địa chỉ của biến ta muốn nhập. Nên khi ra khỏi hàm ta giá trị đó vẫn được giữ nguyên.
Biến con trỏ đặc biệt ở chỗ, giá trị của nó đc xem là 1 địa chỉ. Tức như int a = 10 -> Giá trị của a = 10. -> printf("%d", a) = 10
Nhưng int *p = &a (giả sử &a = 123456) thì giá trị của p = 123456.
Tức khi ra in printf("%d", p) thì ta nhận được 123456. Và *p lúc này mới = 10.
Ở hàm trên bạn dùng scanf cho con trỏ (rows, column), tức đang nhập giá trị cho con trỏ này (tức là đang nhập địa chỉ cho nó trỏ tới luôn), nếu muốn nó ko lỗi thì phải nhập vào là 1 địa chỉ được phép truy cập.
Nhưng bạn nhập test có thể rows w column giá trị < 100 thì vùng nhớ này có thể là vùng được hệ điều hành chiếm giữ nên ko cho phép ai truy cập vào -> Nó quăng ra lỗi not responding gì gì đó và dừng ct luôn. Nếu trên linux sẽ gặp được lỗi segmentation fault.
Vậy nếu muốn nhập giá trị cho biến đang được trỏ bởi con trỏ kia, thì bạn chỉ cần truyền vào giá trị của con trỏ là đủ
Hơi dài dòng xíu nhưng hy vọng bạn hiểu.
hình như cái này thầy em gọi là “miền giá trị của p” thì phải
Có lẽ …
Anh @drgnz cho em hỏi là nếu muốn nhập giá trị vào phần tử đầu tiên của mảng
array
thì đểscanf("<đặc tả>", array);
là được đúng không a ?:)) Bạn cứ thử, test thấy đúng kq là biết mà \ :v /
Ngại gì mà ko thử?
èo lười lắm :))
code html/css có editor online còn test nhanh chứ c/c++ thì bé VS chạy chậm rì mà đứt ruột :((
:~ Thích online thì đây luôn:
Ideone.com
http://rextester.com/l/c_online_compiler_visual
Ideone.com
Ideone is something more than a pastebin; it's an online compiler and debugging tool which allows to compile and run code online in more than 40 programming languages.
Hì ~~
em mới thử thì thấy nếu nhập giá trị cho con trỏ mà để
scanf("%d", &pointer)
là nó lỗi ngay, đểscanf("%d", pointer)
thì ko có gìcái này nghĩa là j vậy ? mình chỉ biết có int *p thôi chứ chưa từng thấy cái này luôn á. Bạn chỉ mình với.
thêm cái này nữa:
@BacNinh mấy cái đó mình làm màu xíu cho đẹp thôi bạn
vì mình muốn code thuần theo C (ko sử dụng tham chiếu) nên khi cấp phát bộ nhớ cho con trỏ cấp 2 thông qua hàm phải tăng nó lên con trỏ cấp 3, và trong hàm đó phải thêm 1 dấu
*
trước mỗi tên mảng.nhưng cũng vì đó mà mình lại bị sai cái lỗi ngớ ngẩn này đây
Trong C ko có tham chiếu nếu muốn truyền tham chiếu một tham số s thì phải ghi tham số hình thức là *s (tức là truyền vào con trỏ đến s). scanf theo nguyên tắc này sẽ nhận s (trong hàm) chứ không phải &s do ta đã có con trỏ đến s (bên ngoài) rồi.
Ví dụ cụ thể: để truyền tham chiếu 1 con trỏ cấp n thì tham số hình thức phải là con trỏ cấp n+1.
Dạ ^^
Code C trên VS riết quen giờ qua Codeblocks nó ko cho dùng tham chiếu, thế là nổ não với con trỏ =))
VS chỉ có trình biên dịch C++ chứ không có C, nó chỉ hỗ trợ đến C89 với ba cái gì đâu nữa là hết.