I wrote a function to get all prime numbers under n in C, and imported it into Python with ctypes.
The function however doesn't return what I expected.
How do I know the size of the returned int* pointer in Python:
primes.c file: It returns a int* pointer of all prime numbers under n
int* primes(int n)
{
  int i, j;
  int *primes = NULL;
  int *prime_numbers = NULL;
  int num_primes = 0;
  
  if (n < 3) {
    printf("n must be >= 3, you input n: %d\n", n);
    return NULL;
  }
  primes = (int *)calloc(n, sizeof(int));
  if (primes == NULL) {
    printf("Memory allocation failed\n");
    return NULL;
  }
  for (i = 0; i < n; i++) {
    primes[i] = 1;
  }
  primes[0] = 0;
  primes[1] = 0;
  
  for (i = 2; i < n; i++) {
    if (primes[i]) {
      for (j = i*2; j < n; j += i) {
        primes[j] = 0;
      }
      num_primes++;
    }
  }
  j = 0;
  prime_numbers = (int *)calloc(num_primes, sizeof(int));
  if (prime_numbers == NULL) {
    printf("Memory allocation failed\n");
    return NULL;
  }
  for (i = 0; i < n; i++) {
    if (primes[i]) {
      prime_numbers[j] = i;
      j++;
    }
  }
  free(primes);
  return prime_numbers;
}
In Python:
import ctypes
from time import perf_counter
library = ctypes.CDLL('./primes.so')
library.primes.argtypes = [ctypes.c_int]
library.primes.restype = ctypes.POINTER(ctypes.c_int)
libc = ctypes.CDLL("libc.so.6")
# ---------------------------------------------------------------------------- #
# --- Primes ----------------------------------------------------------------- #
# ---------------------------------------------------------------------------- #
def primes_c(n: int) -> list[int]:
    assert isinstance(n, int), "n must be an integer."
    assert (n >= 3), "n must be >= 3."
    primes: list[int] = library.primes(n)
    return primes
def main():
    n: int = 10
    print(f"Getting prime numbers under {n:_}.")
    print("C implementation:")
    start = perf_counter()
    prime_numbers_c = primes_c(n)
    end = perf_counter()
    print(f"took {end - start:.2f} seconds.")
    for i in prime_numbers_c:
    print(i)
    libc.free(prime_numbers_c)
    
if __name__ == '__main__':
    main()
My output looks like this, segfaulting
.
.
.
0
0
0
0
0
0
0
[1]    28416 segmentation fault (core dumped)  python3 primes.py