programing

이 메모리 누전 문제를 해결하려면 어떻게 해야 하나요?

randomtip 2022. 9. 23. 21:21
반응형

이 메모리 누전 문제를 해결하려면 어떻게 해야 하나요?

수업 있어요 뉴스

__constructure에서 naviModelNewsColumns 함수를 사용할 수 있습니다.

columns = naviModelNewsColumns();
zend_update_property(Z_OBJCE_P(ZEND_THIS), Z_OBJ_P(ZEND_THIS), ZEND_STRL("columns"), &columns);
zval_ptr_dtor(&columns);

다음은 naviModelNewsColumns 함수입니다.

zval naviModelNewsColumns() {
    zval _1, _2, _3, idLabel, titleLabel, result;

    array_init(&_1);

    array_init(&_2);
    ZVAL_STRING(&idLabel, "ID");
    add_next_index_string(&_2, "id");
    add_assoc_zval(&_2, "label", &idLabel);
    add_assoc_zval(&_1, "id", &_2);

    array_init(&_3);
    ZVAL_STRING(&titleLabel, "Title");
    add_next_index_string(&_3, "title");
    add_assoc_zval(&_3, "label", &titleLabel);
    add_assoc_zval(&_1, "title", &_3);

    ZVAL_ZVAL(&result, &_1, 1, 1);

    return result;
}

모델을 초기화합니다.

$model = new Navi\Model\News();

메모리 누수는 없다.

단, 모델 메서드 "load"를 하나 더 호출하는 경우:

$model = new Navi\Model\News();

$model->load([
    'title' => 'Hello'
]);

메모리 누수는 naviModelNewsColumns 함수의 라인에서 발생합니다.

add_assoc_zval(&_1, "id", &_2);

로드 방법은 다음과 같습니다.

PHP_METHOD(NaviModel, load) {
    zval *dataParam, input, *data, *columns, rv, function;
    bool encode = false;

    ZEND_PARSE_PARAMETERS_START(1, 2)
        Z_PARAM_ZVAL(dataParam)
        Z_PARAM_OPTIONAL
        Z_PARAM_BOOL(encode)
    ZEND_PARSE_PARAMETERS_END();

    if (Z_TYPE_P(dataParam) == IS_NULL) {
        RETURN_TRUE;
    } else if (Z_TYPE_P(dataParam) == IS_OBJECT) {
        zval args[1];

        ZVAL_STRING(&function, "get_object_vars");
        ZVAL_COPY_VALUE(&args[0], dataParam);
        call_user_function(NULL, NULL, &function, &input, 1, args);

        zval_dtor(args);
    } else if (Z_TYPE_P(dataParam) == IS_ARRAY) {
        zval index;
        zend_string *paramKey;

        array_init(&input);

        ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARR_P(dataParam), paramKey, data) {
            ZVAL_STR_COPY(&index, paramKey);

            add_assoc_zval(&input, Z_STRVAL(index), data);
        } ZEND_HASH_FOREACH_END();
    }

    zend_string *key, *empty = zend_string_init(ZEND_STRL(""), 0); // Need initial for release

    columns = zend_read_property(naviModelCe, Z_OBJ_P(ZEND_THIS), ZEND_STRL("columns"), ZEND_FETCH_CLASS_SILENT, &rv);

    if (Z_TYPE_P(columns) == IS_ARRAY) {
        ZEND_HASH_FOREACH_STR_KEY(Z_ARR_P(columns), key) {
            zval index, value;

            ZVAL_STR_COPY(&index, key);
            zval_copy_ctor(&index);

            if (zend_hash_str_exists(Z_ARR(input), Z_STRVAL(index), strlen(Z_STRVAL(index)))) {
                ZVAL_COPY_VALUE(&value, zend_hash_str_find(Z_ARR(input), Z_STRVAL(index), strlen(Z_STRVAL(index))));
                zval_copy_ctor(&value);

                if (Z_TYPE(value) == IS_STRING) {
                    zend_string *trimmed;

                    trimmed = php_trim(Z_STR(value), NULL, 0, 3);

                    if (encode) {
                        zval _3args[3];

                        ZVAL_STRING(&function, "htmlspecialchars");

                        ZVAL_STRING(&_3args[0], ZSTR_VAL(trimmed));
                        ZVAL_LONG(&_3args[1], 3);
                        ZVAL_STRING(&_3args[2], "UTF-8");

                        call_user_function(NULL, NULL, &function, &value, 3, _3args);

                        zval_dtor(_3args);
                    } else {
                        ZVAL_STRING(&value, ZSTR_VAL(trimmed));
                    }

                    zend_string_release(trimmed);
                }

                Z_OBJ_HT_P(ZEND_THIS)->write_property(Z_OBJ_P(ZEND_THIS), Z_STR(index), &value, 0);

                zval_ptr_dtor(&value);
            }

            zval_ptr_dtor(&index);
        } ZEND_HASH_FOREACH_END();
    }

    zend_string_release(key);
    zend_string_release(empty);
    zval_ptr_dtor(&input);

    RETURN_TRUE;
}

다음으로 Valgrind 출력을 나타냅니다.

==68589== Memcheck, a memory error detector
==68589== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==68589== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==68589== Command: /root/php-bin/DEBUG/bin/php ./test/test.php
==68589== Parent PID: 9
==68589== 
==68589== 
==68589== HEAP SUMMARY:
==68589==     in use at exit: 3,541 bytes in 11 blocks
==68589==   total heap usage: 14,052 allocs, 14,041 frees, 2,964,771 bytes allocated
==68589== 
==68589== 32 bytes in 1 blocks are definitely lost in loss record 1 of 8
==68589==    at 0x484EFC8: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==68589==    by 0x6E79C7: __zend_malloc (zend_alloc.c:3056)
==68589==    by 0x6E649B: _malloc_custom (zend_alloc.c:2418)
==68589==    by 0x6E660F: _emalloc (zend_alloc.c:2537)
==68589==    by 0x739393: zend_string_alloc (zend_string.h:144)
==68589==    by 0x739403: zend_string_init (zend_string.h:166)
==68589==    by 0x73CA2B: _zend_hash_str_add_or_update_i (zend_hash.c:869)
==68589==    by 0x73CD9F: zend_hash_str_update (zend_hash.c:932)
==68589==    by 0x72668F: zend_symtable_str_update (zend_hash.h:542)
==68589==    by 0x72D853: add_assoc_zval_ex (zend_API.c:1552)
==68589==    by 0x72B050F: naviModelNewsColumns (news.c:38)
==68589==    by 0x72B0B0B: zim_NaviModelNews___construct (news.c:98)
==68589== 
==68589== LEAK SUMMARY:
==68589==    definitely lost: 32 bytes in 1 blocks
==68589==    indirectly lost: 0 bytes in 0 blocks
==68589==      possibly lost: 0 bytes in 0 blocks
==68589==    still reachable: 3,509 bytes in 10 blocks
==68589==         suppressed: 0 bytes in 0 blocks
==68589== Reachable blocks (those to which a pointer was found) are not shown.
==68589== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==68589== 
==68589== For lists of detected and suppressed errors, rerun with: -s
==68589== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

이 문제를 지적할 수 있도록 도와주실 수 있나요?

언급URL : https://stackoverflow.com/questions/73597705/how-can-i-fix-this-memory-leak-issue

반응형