Solution Idea

50008. Pointer Chasing

範例輸入解釋圖

pointer: 8 bytes, int: 4 bytes.

4776E0 4776E8 4776F0
+--------------------+
|477700|477790|NULL  |
++------+------------+
 |      |
 |      |
 +-----------------> 477700 477708 477710 477718
        |           +---------------------------+
        |           |477730|477750|477770|NULL  |
        |           ++------+------+------------+
        |            |      |      |
        |            |      |      |
        |            |      |      +----> 477770 477774
        |            |      |            +-------------+
        |            |      |            |     8|     0|
        |            |      |            +-------------+
        |            |      |
        |            |      |
        |            |      +-----------> 477750 477754 477758
        |            |                   +--------------------+
        |            |                   |     2|     8|     0|
        |            |                   +--------------------+
        |            |
        |            |
        |            +------------------> 477730 477734 477738 47773C
        |                                +---------------------------+
        |                                |     1|     3|     5|     0|
        |                                +---------------------------+
        |
        |
        +-----------> 477790 477798 4777A0 4777A8 4777A8
                     +----------------------------------+
                     |4777C0|4777E0|477800|477820|NULL  |
                     ++------+------+------+------------+
                      |      |      |      v
                      |      |      |       477820 477824 477828 47782C 477730
                      |      |      |      +----------------------------------+
                      |      |      |      |     5|     5|     6|     6|     0|
                      |      |      |      +----------------------------------+
                      |      |      |
                      |      |      +-----> 477800 477804
                      |      |             +-------------+
                      |      |             |     7|     0|
                      |      |             +-------------+
                      |      |
                      |      +------------> 4777E0 4777E4 4777E8 4777EC
                      |                    +---------------------------+
                      |                    |     1|     2|     8|     0|
                      |                    +---------------------------+
                      |
                      |
                      +-------------------> 4777C0 4777C4 4777C8 4777CC 4777D0
                                           +----------------------------------+
                                           |     1|     3|     5|     2|     0|
                                           +----------------------------------+

setmatrix.h

1
void processSetMatrix(int ***ptr);

setmatrix.c

version 1

  • ptr[i] 等價於 *(ptr+i)
  • ptr[i][j] 等價於 *(*(ptr+i) + j)
  • ptr[i][j][k] 等價於 *(*(*(ptr+i) + j) + k)

因此若要得到 10 pt,只需要 printf("%d\n", *(*(*(ptr+0) + 0) + 0));,也就是 printf("%d\n", ***ptr); 即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "setmatrix.h"
#include <stdlib.h>
 
void processSetMatrix(int ***ptr) {
    int f = 0;
    for (int i = 0; ptr[i]; i++) {
        for (int j = 0; ptr[i][j]; j++) {
            for (int k = 0; ptr[i][j][k]; k++) {
                int v = ptr[i][j][k];
                if (f)    putchar(' ');
                printf("%d", v);
                f = 1;
            }
        }
    }
    puts("");
}

version 2

修改從 B02902095 的寫法,這寫法很有意思,但會修改儲存數值,函數返回後,會造成無法回收記憶體。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<stdio.h>
 
void processSetMatrix(int ***ptr) {
    while (*ptr != NULL) {
        while (**ptr != NULL) {
            while (***ptr != 0) {
                printf("%d ", ***ptr);
                (**ptr)++;
            }
            (*ptr)++;
        }
        ptr++;
    }
    return;
}

會修改的原因是這樣子,現在按照範例輸入來解釋這份 code。

  1. while (*ptr != NULL) => while (477700 != NULL) 成立
  2. while (**ptr != NULL) => while (477730 != NULL) 成立
  3. while (***ptr != NULL) => while (1 != 0) 成立,並且輸出 1。
  4. (**ptr)++; 相當於把位址 477700 的數值 ++,意即 addr[477700] = 477734
  5. while (***ptr != NULL) => while (3 != 0) 成立,並且輸出 3。
  6. (**ptr)++; 相當於把位址 477700 的數值 ++,意即 addr[477700] = 477738
  7. while (***ptr != NULL) => while (5 != 0) 成立,並且輸出 5。
  8. (**ptr)++; 相當於把位址 477700 的數值 ++,意即 addr[477700] = 47773C
  9. while (***ptr != NULL) => while (0 != 0) 不成立。
  10. 執行 (*ptr)++; 相當於把位址 4776E0 的數值 ++,意即 addr[4776E0] = 477708
  11. 如此類推。

過程中變動原本陣列的數值,這也導致一些問題。如果呼叫兩次 void processSetMatrix(int ***ptr);,則這個程序輸出會錯。

Author

Morris

Discussion