[英]Variable sized arrays and array pointer in C
我正在HackerRank中進行編碼練習。 在C ++的Variable Sized Arrays練習中,我嘗試用C做,但我無法做到。
我的代碼有時會傳遞簡單的測試用例0,但有時不會。 代碼完全相同,但出現了不同的答案。
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int n, q;
scanf("%d%d", &n, &q);
int *p_arr[n];
if (n > 0) {
for (int i = 0; i < n; i++) {
int tmp;
scanf("%d", &tmp);
int tmp_arr[tmp];
p_arr[i] = tmp_arr;
for (int j = 0; j < tmp; j++) {
int value;
scanf("%d", &value);
p_arr[i][j] = value;
printf("%d ", p_arr[i][j]);
}
printf("\n");
}
}
if (q > 0) {
for (int i = 0; i < q; i++) {
int row, col;
scanf("%d%d", &row, &col);
printf ("%d %d\n", row, col);
int answer = p_arr[row][col];
printf("%d\n", answer);
}
}
return 0;
}
這是我得到的錯誤答案
1 5 4
1 2 8 9 3
0 1
21973
1 3
32764
我不知道21973
和32764
來自哪里。
這是我預期的答案
1 5 4
1 2 8 9 3
0 1
5
1 3
9
有時我得到了錯誤的答案,有時我得到了正確的答案。 那是為什么? 非常感謝!
繼續注釋,如果練習涉及可變長度數組,那么它應該用C語言編寫,因為C ++標准不提供VLA(並且在添加C99后它們在C11中開始是可選的)
代碼的主要問題(除了完全分配輸入失敗之外)是它調用Undefined Behavior,因為int tmp_arr[tmp]
在for
循環結束時超出了范圍。 用p_arr[i] = tmp_arr;
分配的p_arr[i] = tmp_arr;
循環外不再存在因為tmp_arr
不再存在。 超出范圍后訪問值的任何嘗試都會調用未定義的行為 ,請參閱未定義,未指定和實現定義的行為
每次處理輸入時,必須驗證輸入是否成功,並且獲得的值是否在有效范圍內。 例如, n
和q
必須是正值。 使用scanf
你可以做到(最低限度)
if (scanf("%d%d", &n, &q) != 2 || n <= 0 || q <= 0) {
fputs ("error: invalid format or value.\n", stderr);
return 1;
}
以上驗證了收到2個輸入並且兩者都是正值。
為了保留用p_arr[i] = tmp_arr;
分配的指針p_arr[i] = tmp_arr;
, tmp_arr
必須是一個已分配的類型來處理一個未知的tmp
數量的元素,或者它必須在循環外聲明(並且足夠大以處理所有預期值 - 假設tmp
被讀作輸入 - 看起來不像預期的方法)。 你不能聲明tmp_arr
靜態無論是作為只會有一個實例,並反復分配給它p_arr[i]
會留下的所有元素p_arr[i]
指向同一個地方。
只需為tmp_arr
分配,然后對p_arr[i]
的賦值將在程序的生命周期中存活或直到它被釋放,例如
int *tmp_arr = calloc (tmp, sizeof *tmp_arr); /* allocate */
if (!tmp_arr) { /* validate every allocation */
perror ("calloc-tmp_arr");
return 1;
}
p_arr[i] = tmp_arr;
( 注: calloc
上面用作零新分配的內存可以使用。 malloc
,而不是因為代碼分配給每個元素)
完全放入並添加(最小)驗證,您可以執行類似於以下操作:
#include <stdio.h>
#include <stdlib.h>
int main (void) {
int n, q; /* validate EVERY input */
if (scanf("%d%d", &n, &q) != 2 || n <= 0 || q <= 0) {
fputs ("error: invalid format or value.\n", stderr);
return 1;
}
int *p_arr[n]; /* array of n-pointers to int */
for (int i = 0; i < n; i++) {
int tmp;
if (scanf("%d", &tmp) != 1 || tmp <= 0) { /* validate! */
fputs ("error: invalid input - tmp.\n", stderr);
return 1;
}
int *tmp_arr = calloc (tmp, sizeof *tmp_arr); /* allocate */
if (!tmp_arr) { /* validate every allocation */
perror ("calloc-tmp_arr");
return 1;
}
p_arr[i] = tmp_arr;
for (int j = 0; j < tmp; j++) {
int value;
if (scanf("%d", &value) != 1) { /* validate! */
fputs ("error: invalid input - value.\n", stderr);
return 1;
}
p_arr[i][j] = value;
printf ("%d ", p_arr[i][j]);
}
putchar ('\n'); /* no need to printf a single-character */
}
for (int i = 0; i < q; i++) {
int row, col; /* validate! */
if (scanf ("%d%d", &row, &col) != 2 || row < 0 || col < 0) {
fputs ("error: invalid input, row or col.\n", stderr);
return 1;
}
printf ("%d %d\n%d\n", row, col, p_arr[row][col]);
}
for (int i = 0; i < n; i++)
free (p_arr[i]);
return 0;
}
( 注意:未經測試,因為沒有提供hackerrank輸入)
仔細看看,如果您有其他問題,請告訴我。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.