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