VarSetCapacity()

변수의 가용 능력을 확대하거나 그의 메모리를 해제합니다. 보통, 이것은 DllCall()과 같이 비정상적인 상황에서만 필요합니다.

GrantedCapacity := VarSetCapacity(TargetVar , RequestedCapacity, FillByte)

매개변수

TargetVar

A reference to a variable. 예를 들어: VarSetCapacity(MyVar, 1000). Array%i%이나 함수의 ByRef 매개변수와 같이 동적 변수도 될 수 있습니다.

RequestedCapacity

생략하면, 변수의 현재 가용능력이 반환됩니다. 그리고 그의 내용은 변경되지 않습니다. 그렇지 않으면, 현재 변수에 있는 모든 것이 사라집니다 (변수가 비워집니다).

RequestedCapacity에 변수가 조정 후에 보유해야할 바이트 개수를 지정하십시오. 유니코드 문자열에 대하여, 이것은 그 길이의 두 배가 되어야 합니다. RequestedCapacity는 내부의 종료 문자를 포함하지 않습니다. 예를 들어 1로 설정하면 그 변수는 1 바이트에다 그의 종료 문자를 더 보유할 수 있습니다. 주의: 나중에 스크립트가 이 변수에 더 큰 값을 할당하면 자동으로 확장됩니다.

이 함수는 종종 그냥 변수가 최소한의 가용능력을 갖추었는지 확인하기 위하여 호출되기 때문에, 수행성능의 이유로, RequestedCapacity가 0일 때만 그 변수를 축소합니다. 다른 말로, 변수의 가용 능력이 이미 RequestedCapacity보다 크면, 축소되지 않습니다 (그러나 그 변수는 일관성을 위해 여전히 비워집니다).

그러므로, 명시적으로 변수를 축소하려면, 먼저 그의 메모리를 VarSetCapacity(Var, 0)으로 해제한 다음 VarSetCapacity(Var, NewCapacity)을 사용하십시오 -- 또는 그냥 필요하면 0으로부터 자동 확장되도록 그대로 두십시오

수행성능의 이유로, 이전의 가용능력이 64 문자보다 작은 (유니코드 빌드에서는 128 바이트보다 작은) 변수는 해제해도 아무 효과가 없을 수 있습니다. 왜냐하면 그의 메모리가 영구 유형이기 때문입니다. 이 경우, 0이 아니라 현재 가용능력이 반환됩니다.

수행성능의 이유로, 가용 능력이 4096 바이트보다 작은 변수의 메모리는 빈 문자열을 저장해도 해제되지 않습니다 (예, Var := ""). 그렇지만, VarSetCapacity(Var, 0)는 변수를 해제합니다.

[v1.0.44.03+]: -1을 RequestedCapacity에 지정하면 변수의 내부에 저장된 문자열 길이를 현재 내용의 길이로 갱신할 수 있습니다. 변수가 간접적으로 변경되는 경우에 유용합니다. 예를 들어 DllCall()를 통하여 그의 주소를 건네는 경우 유용합니다. 이 모드에서, VarSetCapacity()는 가용능력이 아니라 그 길이를 바이트 단위로 돌려줍니다.

FillByte

이 매개변수는 보통 생략됩니다. 생략되면 목표 변수의 메모리가 초기화되지 않습니다 (대신에, 그 변수는 단순히 위에 기술한 바와 같이 비워집니다). 그렇지 않으면, 0에서 255 사이의 숫자를 지정하십시오. 목표 변수의 메모리 구역이 (그의 현재 가용 능력, RequestedCapacity보다 더 클수 있습니다 매 바이트마다 그 숫자로 채워집니다). 0이 지금까지 가장 흔히 사용되는 값입니다. 이 값은 DllCall 구조와 같이 변수에 날 이진 데이터를 담아야 할 경우에 유용합니다.

반환 값

This function returns the number of bytes that Var can now hold, which will be greater than or equal to RequestedCapacity. TargetVar이 유효한 변수 이름이 아니면 (문자 그대로의 문자열 또는 숫자이면), 0이 반환됩니다. (아주 희귀하지만) 시스템에 충분한 메모리가 없어서 변경이 불가능하면, 에러 대화상자가 나타나고 현재 가용 능력이 반환됩니다 - 이 행위는 미래 버전에서는 바뀔 수 있습니다.

논평

DllCall()에 기술된 사용법 외에도, 이 함수는 점진적인 결합으로 문자열을 구성할 때 수행성능을 향상시키는 데에도 사용할 수 있습니다. 왜냐하면 그 문자열의 최종 길이가 얼마인지 알고 있다면 여러 자동 크기 변경 부담을 피할 수 있기 때문입니다. 그런 경우 RequestedCapacity는 정확할 필요가 없습니다 가용 능력이 작으면, 수행성능이 더욱 개선됩니다. 그리고 가용 능력이 소진될 때 자동으로 변수가 확장을 시작할 것입니다. 가용 능력이 크면, 메모리가 낭비됩니다. 그러나 잠시일 뿐입니다. 왜냐하면 연산 후에 VarSetCapacity(Var, 0) 또는 Var := ""를 수단으로 모든 메모리를 해제할 수 있기 때문입니다

#MaxMem는 변수가 스스로 행하는 자동 확장만 제한합니다. VarSetCapacity에 영향을 주지 않습니다.

DllCall(), #MaxMem, NumPut(), NumGet()

예제

MyVar가 작업에 충분한 여유 공간을 확보하고 있는지 확인하여 최적화합니다.

VarSetCapacity(MyVar, 10240000)  ; ~10 MB
Loop
{
    ; ...
    MyVar .= StringToConcatenate
    ; ...
}

Use a variable to receive a string from an external function via DllCall().

; 문자열에 대하여 필요한 버퍼 공간을 계산합니다.
bytes_per_char := A_IsUnicode ? 2 : 1
max_chars := 500
max_bytes := max_chars * bytes_per_char

Loop 2
{
    ; DllCall에 사용할 공간을 할당합니다.
    VarSetCapacity(buf, max_bytes)

    if (A_Index = 1)
        ; DllCall을 통하여 변수를 간접적으로 변경합니다.
        DllCall("wsprintf", "Ptr", &buf, "Str", "0x%08x", "UInt", 4919)
    else
        ; 길이를 자동으로 갱신하려면 "str"를 사용합니다:
        DllCall("wsprintf", "Str", buf, "Str", "0x%08x", "UInt", 4919)

    ; 왜 길이를 갱신한 필요가 있는지 보여주기 위해 문자열을 결합합니다:
    wrong_str := buf . "<end>"
    wrong_len := StrLen(buf)

    ; 변수의 길이를 갱신합니다.
    VarSetCapacity(buf, -1)

    right_str := buf . "<end>"
    right_len := StrLen(buf)

    MsgBox,
    (
    업데이트 전
      문자열: %wrong_str%
      길이: %wrong_len%

    업데이트 후
      문자열: %right_str%
      길이: %right_len%
    )
}