realloc으로 다이나믹하게 array 사이즈를 변경시키는 Dynamic Array구현 가능.
vector의 push_back() 구현. 약간 OOP스럽게 구현해봤다. 앞으로 유용하게 쓸듯!
#include <stdio.h>
#include <stdlib.h>
struct elem {
int val;
};
struct vector {
int v_size;
int v_last;
struct elem *arr;
void (*push_back)(struct vector *, int);
};
void cb_push_back(struct vector *this, int val)
{
if (this->v_last >= this->v_size) {
this->v_size *= 2; // increase by double size
this->arr = (struct elem *)realloc(this->arr, sizeof(struct elem) * this->v_size);
printf("resize vector by %d (val:%d)\n", this->v_size, val);
}
this->arr[this->v_last++].val = val;
}
struct vector *vector_init(int size)
{
struct vector *v = (struct vector *)calloc(1, sizeof(struct vector));
v->push_back = cb_push_back; // assign call back function
v->v_last = 0; // last idx
v->v_size = size;
v->arr = (struct elem *)calloc(v->v_size, sizeof(struct elem));
return v;
}
int main(int argc, char *argv[])
{
struct vector *myvt = vector_init(1);
myvt->push_back(myvt, 10);
myvt->push_back(myvt, 20);
myvt->push_back(myvt, 30);
myvt->push_back(myvt, 40);
myvt->push_back(myvt, 50);
myvt->push_back(myvt, 60);
myvt->push_back(myvt, 70);
myvt->push_back(myvt, 80);
myvt->push_back(myvt, 90);
myvt->push_back(myvt, 100);
for (int i = 0; i < myvt->v_last; i++)
printf("(%d)", myvt->arr[i].val);
printf("\n");
return 0;
}
실행 결과
$ ./ra
resize vector by 2 (val:20)
resize vector by 4 (val:30)
resize vector by 8 (val:50)
resize vector by 16 (val:90)
(10)(20)(30)(40)(50)(60)(70)(80)(90)(100)
malloc() + memset()
vs calloc()
성능 비교로컬에서 돌려보니 놀랍게도 calloc이 malloc + memset조합보다 월등히 빠르다. (적어도 아래 코드를 로컬에서 실행했을때). 아래 답변에 따르면 보통 비슷한데 calloc은 보다 일을 적게할수 있기때문이다. memset()하는 부분을 skip할 수도 있기 때문. 그런데 malloc() + memset() 은 모두 fully하게 실행된다. 자세한 내용은 아래 출처 참고.
출처: https://stackoverflow.com/questions/2688466/why-mallocmemset-is-slower-than-calloc
$ time ./ma
real 0m4.446s
user 0m1.191s
sys 0m3.253s
$ time ./ca
real 0m0.100s
user 0m0.039s
sys 0m0.048s
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define BLOCK_SIZE 1024*1024*256
#define BUF_SIZE 50
int main()
{
int i=0;
char *buf[BUF_SIZE];
while(i < BUF_SIZE) {
buf[i] = (char*)malloc(BLOCK_SIZE);
memset(buf[i], 0, BLOCK_SIZE);
i++;
}
}
#include<stdio.h>
#include<stdlib.h>
#define BLOCK_SIZE 1024*1024*256
#define BUF_SIZE 50
int main()
{
int i=0;
char *buf[BUF_SIZE];
while(i < BUF_SIZE) {
buf[i] = (char*)calloc(1, BLOCK_SIZE);
i++;
}
}
all: ca ma
calloc.o: calloc.c
gcc -c calloc.c -o calloc.o
malloc.o: malloc.c
gcc -c malloc.c -o malloc.o
ca: calloc.o
gcc calloc.o -o ca
ma: malloc.o
gcc malloc.o -o ma
clean:
rm -rf *.o
rm ca ma