💾 Archived View for thrig.me › blog › 2024 › 03 › 19 › c-arrays.gmi captured on 2024-05-12 at 15:09:14. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2024-03-21)

-=-=-=-=-=-=-

C Arrays

"I watched C-pointers glitter in the dark near Tannhäuser Gate…"

It's a three by three array in C, how hard could it be to have a function to loop over that array and show what's in the grid?

    #include <stdio.h>
    void show(int **gp, size_t rows, size_t cols) {
        for (size_t r = 0; r < rows; ++r) {
            for (size_t c = 0; c < cols; ++c)
                printf("%d", gp[r][c]);
            putchar('\n');
        }
    }
    int main(int argc, char *argv[]) {
        int grid[3][3] = { {1, 2, 3},
                           {4, 5, 6},
                           {7, 8, 9} };
        show((int **)grid, 3, 3);
    }

threeby.c

    $ make threeby && ./threeby
    cc -O2 -pipe     -o threeby threeby.c
    Segmentation fault (core dumped)

Time may be spent in a debugger or doing printf of "%p" on "(void *)gp" and such, the gist of which is that the memory addresses are totally wrong in the "show" function, and bad memory access results in process death. Or you could read various documentation and conclude that while there are various solutions,

    void show(int *gp, size_t rows, size_t cols) {
        for (size_t r = 0; r < rows; ++r) {
            for (size_t c = 0; c < cols; ++c) {
                //printf("%d", *(gp + (r * cols) + c));
                printf("%d", (gp + r * cols)[c]);
            }
            putchar('\n');
        }
    }

you might be better off allocating a NxM matrix and passing that around rather than to try to make a fixed allocation work with a function that the compiler has no idea what the array dimensions are.

grid-factory.c

Other languages

How does this work in other languages? There may be extra metadata so that you can query the size of the array, not loop over invalid memory addresses, and other such important details. Often this comes with overhead.

    $ perl -MDevel::Peek -e '@x = 57..99; Dump \@x'
    SV = IV(0xfa58e60b7f8) at 0xfa58e60b808
      REFCNT = 1
      FLAGS = (TEMP,ROK)
      RV = 0xfa585c32a48
      SV = PVAV(0xfa6226950d8) at 0xfa585c32a48
        REFCNT = 2
        FLAGS = ()
        ARRAY = 0xfa585c2b180
        FILL = 42
        MAX = 42
        FLAGS = (REAL)
        Elt No. 0
        SV = IV(0xfa62269e648) at 0xfa62269e658
          REFCNT = 1
          FLAGS = (IOK,pIOK)
          IV = 57
    ...

Random array dimensions? Can do!

    (block nil (setq *random-state* (make-random-state t)) (return))

    (defun some-random-numbers ()
      (loop repeat (+ 3 (random 5)) collect (1+ (random 7))))

    (defun random-array ()
      (make-array (some-random-numbers)))

    (loop repeat 4 do
      (format t "~&~a~&" (array-dimensions (random-array))))

See Also

"Understanding and Using C Pointers". Richard M Reese. 2013.

Ideally you brush up on these details before getting into a time limited programming challenge, but you may not know what you're weak on until you get into a time limited programming challenge.