C, 174 (167) 152 바이트
재귀 함수 f
, 메모리 누수 ( 152 ) :
#include"object.h"
size_t f(array_t*a){size_t t=0,i=0;for(;i<array_length(a);i++){object_t*o=array_get_copy(a,i,0);t+=o->type==6?f(o->ary):1;}return t;}
167f
에서 참조를 사용하여 누출되지 않는 재귀 :
#include"object.h"
size_t f(array_t*a){size_t t=0,i=0;for(;i<array_length(a);i++){object_t**o=array_get_ref(a,i,0);t+=*o->type==t_array?f(*o->ary):1;}return t;}
언 골프 드 :
size_t get_recursize (const array_t* const a) {
pfn();
object_failnull(a);
size_t out = 0;
for (size_t i = 0; i < array_length(a); i++) {
object_t** o = array_get_ref(a, i, NULL);
if ( (*o)->type == t_array ) {
out += get_recursize((*o)->ary);
} else {
++out;
}
}
return out;
}
"그러나 어떻게 C에 응답 할 수 있습니까? C에는 관리되는 배열이 없으며 실제로 이기종 배열을 가질 수 없습니다 ...?"
"Aha는"(GNU-ish) C11 및 ISO C ++ 11에 대한 간단한 "개체"시스템에서 작업하고 있기 때문에 대답했습니다. "
이 기능의 전체 데모 프로그램은 다음과 같습니다.
#include "../calc/object/object.h"
size_t get_recursize (const array_t* const a);
define_array_new_fromctype(ssize_t);
int main (void) {
size_t len = 6;
static const ssize_t h[6] = { -1, 3, -5, 7, -9, 11 };
array_t* a = array_new_from_ssize_t_lit(h, len, t_realint);
size_t rsize = get_recursize(a);
printf("Recursive size of a: %zu\n", rsize);
object_t* asobj = object_new(t_array, a);
array_destruct(a);
array_t* b = array_new(NULL, -1);
for (size_t j = 0; j < 10; j++) {
array_append(b, asobj);
}
object_destruct(asobj);
rsize = get_recursize(b);
printf("Recursive size of b: %zu\n", rsize);
asobj = object_new(t_array, b);
array_destruct(b);
array_t* c = array_new(NULL, -1);
for (size_t i = 0; i < 100; i++) {
array_append(c, asobj);
}
object_destruct(asobj);
rsize = get_recursize(c);
printf("Recursive size of c: %zu\n", rsize);
array_destruct(c);
return EXIT_SUCCESS;
}
size_t get_recursize (const array_t* const a) {
pfn();
object_failnull(a);
size_t out = 0;
for (size_t i = 0; i < array_length(a); i++) {
object_t** o = array_get_ref(a, i, NULL);
if ( (*o)->type == t_array ) {
out += get_recursize((*o)->ary);
} else {
++out;
}
}
return out;
}
지금 여기 살아요 있으며 이것을 사용하려면 해당 저장소가 필요합니다.
또한 libfnv
플랫폼 용으로 컴파일 된 Fowler-Noll-Vo 해시 라이브러리가 필요합니다 . 해당 저장소에 있으며 여기에서 가져올 수도 있습니다 .
그럼 넌 할 수있어 cc -DNODEBUG size.c path/to/libfnv.a -o size
.
구현이 반드시 효율적인 것은 아닙니다.
$ valgrind --leak-check=full --track-origins=yes --show-leak-kinds=all ./size
==24127== Memcheck, a memory error detector
==24127== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==24127== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==24127== Command: ./size
==24127==
Recursive size of a: 6
Recursive size of b: 60
Recursive size of c: 6000
==24127==
==24127== HEAP SUMMARY:
==24127== in use at exit: 0 bytes in 0 blocks
==24127== total heap usage: 22,900 allocs, 22,900 frees, 615,584 bytes allocated
==24127==
==24127== All heap blocks were freed -- no leaks are possible
==24127==
==24127== For counts of detected and suppressed errors, rerun with: -v
==24127== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
그러나 작동합니다! 마스터에 대한 마지막 커밋 (이 프로그램이 컴파일 된)은 2 일 전이었습니다. 이는이 제출이 유효 함을 의미합니다.