//
// void_arr.c
//
// Void pointer array
//
#include <stdlib.h>
#define ARR_INIT_CAP 2
#define ARR_GROW_RAT 2
#define TYPE void *
struct arr {
TYPE *buf;
int len;
int cap;
};
struct arr *arrnew(void);
struct arr *arrnewcap(int);
void arrdelete(struct arr *);
int arrappend(struct arr *, TYPE);
int arrresize(struct arr *, int);
TYPE arrremove(struct arr *);
inline struct arr *
arrnew(void)
{
return arrnewcap(ARR_INIT_CAP);
}
inline struct arr *
arrnewcap(int cap)
{
struct arr *arr;
if ((arr = malloc(sizeof(struct arr))) == NULL) {
return NULL;
}
if ((arr->buf = malloc(cap * sizeof(TYPE))) == NULL) {
free(arr);
return NULL;
}
arr->len = 0;
arr->cap = cap;
return arr;
}
inline void
arrdelete(struct arr *arr)
{
free(arr->buf);
free(arr);
}
inline int
arrappend(struct arr *arr, TYPE val)
{
if (arr->cap <= arr->len && arrresize(arr, arr->cap * ARR_GROW_RAT) == -1) {
return -1;
}
arr->buf[arr->len++] = val;
return 0;
}
inline int
arrresize(struct arr *arr, int ncap)
{
TYPE *nbuf;
if ((nbuf = realloc(arr->buf, ncap * sizeof(TYPE))) == NULL) {
return -1;
}
arr->cap = ncap;
arr->buf = nbuf;
return 0;
}
inline TYPE
arrremove(struct arr *arr)
{
return arr->buf[--arr->len];
}
////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#define LIMIT 100
int a = 0;
int b = 1;
int get(void)
{
int tmp = a;
a = b;
b = tmp + b;
return tmp;
}
void reset(void)
{
a = 0;
b = 1;
puts("--");
}
void process_int(int i)
{
printf("%d\n", i);
}
void process_intp(int *ip)
{
printf("%d\n", *ip);
}
void process_charp(char *cp)
{
printf("%s\n", cp);
}
int main(int argc, char *argv[])
{
int i, *ip, num;
struct arr *arr;
int limit = argc < 2 ? LIMIT : atoi(argv[1]);
printf("sizeof(int) = %zu\n", sizeof(int));
printf("sizeof(int *) = %zu\n", sizeof(int *));
printf("sizeof(void *) = %zu\n", sizeof(char *));
// int (wrong)
arr = arrnew();
while ((num = get()) < limit) {
// warning: passing argument 2 of ‘arrappend’ makes pointer from integer without a cast [-Wint-conversion]
// arrappend(arr, num);
// ^
// note: expected ‘void *’ but argument is of type ‘int’
// arrappend(struct arr *arr, TYPE val)
// ^
// arrappend(arr, num);
// warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
// arrappend(arr, (void *)num);
// ^
arrappend(arr, (void *)num);
}
for (i = 0; i < arr->len; ++i) {
process_int(arr->buf[i]);
}
for (i = arr->len-1; i > 0; --i) {
arr->buf[i] -= arr->buf[i-1];
}
for (i = arr->len-1; i >= 0; --i) {
process_int(arrremove(arr));
}
arrdelete(arr);
// int *
reset();
arr = arrnew();
while ((num = get()) < limit) {
ip = malloc(sizeof(int));
*ip = num;
arrappend(arr, ip);
}
for (i = 0; i < arr->len; ++i) {
process_intp(arr->buf[i]);
}
for (i = arr->len-1; i > 0; --i) {
*(int *)(arr->buf[i]) -= *(int *)(arr->buf[i-1]);
}
for (i = arr->len-1; i >= 0; --i) {
process_intp(arrremove(arr));
free(arr->buf[arr->len]);
}
arrdelete(arr);
// char *
arr = arrnew();
arrappend(arr, "one");
arrappend(arr, "two");
arrappend(arr, "three");
for (i = 0; i < arr->len; ++i) {
process_charp(arr->buf[i]);
}
arrdelete(arr);
return 0;
}