OOP에 대한 도움말 - 페이지 2

 
Ihor Herasko # :
갑자기 Renat에서 논쟁하고 싶다면 환영 합니다.

어, 이렇게:

이호르 헤라스코 # :

그리고 잠시. 포인터를 통해 개체 배열을 만드는 것이 좋습니다. 그렇지 않으면 스택 메모리에 매우 작은 배열을 얻습니다.

Renat이 말한 것과 위의 예와 아무 관련이 없습니다.
 
Ihor Herasko # :

로컬 수준에서 선언하고 그렇게 끔찍하지 않은 숫자를 입력하여 예제를 약간 변경하면 컴파일러는 문제가 정확히 무엇인지에 대해 이미 일반 텍스트로 작성합니다.

갑자기 Renat에서 논쟁하고 싶다면 환영 합니다.

자신의 예에서:

Test *pClassTest[];

함수 외부에서 전역 변수로 정의됩니다. 여기 스택은 무엇입니까? 그것은 힙입니다.

 
Vasiliy Sokolov # :

자신의 예에서:

함수 외부에서 전역 변수로 정의됩니다. 여기 스택은 무엇입니까? 그것은 힙입니다.

대박! Vasily, 당신은 당신이 논쟁하는 것을 이해하지 못하고 논쟁이 무엇에 관한 것인지 이해하려고 노력하지 않고 논쟁에 참여 했습니까?

Igor는 이것이 힙에 필요하다고 주장하며 이 코드 줄은 컴파일되지 않는(그리고 포인터가 없는) 첫 번째 것과 달리 컴파일되는 두 번째("올바른") 예제에서 가져온 것입니다.

 
Ihor Herasko # :

로컬 수준에서 선언하고 그렇게 끔찍하지 않은 숫자를 입력하여 예제를 약간 변경하면 컴파일러는 문제가 정확히 무엇인지에 대해 이미 일반 텍스트로 작성합니다.

갑자기 Renat에서 논쟁하고 싶다면 환영 합니다.

"끔찍하지 않은"계정으로. 말하는 방법. 기본 스택은 1MB이고 ARRAY_SIZE*sizeof(Test)를 할당합니다. 이는 분명히 더 큽니다.

 
Ihor Herasko # :

이것은 문제가 아니며 잠재적인 문제는 훨씬 적습니다. MT에서 메모리로 작업하는 기능만 있습니다. 다음은 정적 배열입니다.

다음은 동적 배열입니다.

이 경우 모든 것이 컴파일되고 작동합니다.

이동합니다.

첫 번째 경우에는 컴파일 시간에 메모리가 할당됩니다. 즉, 프로그램의 .data 세그먼트에는 이러한 ARRAY_SIZE*sizeof(Test)가 포함되어야 합니다. ARRAY_SIZE가 얼마였나요?))) 제가 틀리지 않았다면 2TB .ex5 이하의 파일이 나옵니다))))

두 번째 경우 ARRAY_SIZE*sizeof(Test*) 바이트가 힙에 할당됩니다. 480GB,

 

더블 x[268435448]; 일반 섹션에서 컴파일됩니다.

268435449 - 더 이상 컴파일되지 않음

그리고 스크립트의 OnStart()에서 268435449가 컴파일되고 일반 섹션에 이 거대한 배열 x가 남습니다.

268435448*8= 2147483584 는 2개의 공연입니다.

***

그리고 함수의 한계는 다음과 같습니다. double x[268435456];

 

스택에 대해 오른쪽을 보십시오.

MQL5 프로그램의 스택 크기를 지정하며 재귀 함수 호출의 경우 충분한 스택이 필요합니다.

스크립트 또는 Expert Advisor가 실행되면 차트에 최소 8Mb의 스택이 할당되고 지표에 대해 속성이 작동하지 않습니다. 스택은 항상 1Mb의 고정 크기입니다.

테스터에서 실행될 때 프로그램에는 항상 16MB의 스택이 할당됩니다.


아마도 스택은 재귀 함수 호출에만 사용됩니다. 따라서 정적 배열의 크기에 관계없이 재귀 호출의 경우 스택은 그대로 유지됩니다.

 
Dmitry Fedoseev # :

대박! Vasily, 당신은 당신이 논쟁하는 것을 이해하지 못하고 논쟁이 무엇에 관한 것인지 이해하려고 노력하지 않고 논쟁에 참여 했습니까?

Igor는 이것이 힙에 필요하다고 주장하며 이 코드 줄은 컴파일되지 않는(그리고 포인터가 없는) 첫 번째 것과 달리 컴파일되는 두 번째("올바른") 예제에서 가져온 것입니다.

확인. 이해가 안 됩니다. 이해했나요? 정확히 이해가 되셨나요? 정확히 정확히?

논쟁은 다음 진술로 요약됩니다.

거래, 자동 거래 시스템 및 거래 전략 테스트에 관한 포럼

OOP에 대한 도움말

이호르 헤라스코 , 2021.09.19 21:00

그리고 한 순간. 포인터를 통해 개체 배열을 만드는 것이 좋습니다. 그렇지 않으면 스택 메모리에 매우 작은 배열을 얻습니다.

Strategy2 *pZ[]; 

이것은 잘못된 진술입니다. 스택의 배열은 할당되지 않습니다 . 포인터를 통해서도, 정적으로도 아닙니다. 이것은 확인하기 쉽습니다.

두 번째 요점: 예제에서는 포인터를 사용하지만 포인터는 필요하지 않습니다. 다음은 ballerplate가 없는 동등한 예입니다.

 #define               ARRAY_SIZE           int ( 60000000 )
class Test
{
public :
   int                nA;
   double             fB;
   datetime           dtC;

                     Test( void )
                       : nA( 0 )
                       , fB( 1.0 )
                       , dtC( __DATETIME__ )
                     {
                     };
};

Test pClassTest[];
 
void OnStart ()
{
   if ( ArrayResize (pClassTest, ARRAY_SIZE) != ARRAY_SIZE)
   {
       Alert ( "Not enought memory" );
       return ;
   }
}

동일한 60,000,000개 개체가 기본 생성자 호출로 할당됩니다. 동시에 수동으로 초기화한 다음 메모리를 해제할 필요가 없으므로 (때로는) 시간이 크게 절약되고 코드가 훨씬 안전하고 간단해집니다.

우리는 확인합니다. 우리는 휴식을 취하고 프로세스 관리자에서 엽니 다. 여기 ProcessHacker에서:

전용 영역에는 각각 4GB와 2GB가 할당됩니다.

스택 크기 확인:


스크립트 스택은 8MB이며 이것이 최대 스택입니다.

머리 속의 논리를 켜고 각각 20바이트의 60,000,000개 개체가 1GB 이상의 메모리를 차지할 것이라고 계산하는 것은 쉽습니다. 단일 스택으로 이를 포함할 수 없습니다.

이 경우 두 예제(포인터가 있는 경우와 없는 경우 모두)는 동일한 프로파일링을 제공합니다. 스택에는 아무 것도 할당되지 않습니다. 그러나 포인터가 있는 예제는 1GB 더 많은 메모리를 할당하므로 확인하기 쉽습니다.

추신 프로그램을 실행하는 동안 최대 스택 크기를 가져오고 변경할 수 없습니다. 최대 스택 크기는 미리 결정되며 예를 들어 컴파일 중에 미리 설정됩니다.

z.s.s. 순전히 이론적으로 스택에 작은 정적 배열을 할당하는 것이 가능합니다(mql에서는 명시적이지 않음). 그러나 이것은 사용자가 서로 다른 켤레 함수에서도 이러한 배열을 여러 개 매우 쉽게 생성하여 스택을 오버플로할 수 있기 때문에 큰 문제로 이어질 수 있습니다. 따라서 사용자는 이러한 석궁으로부터 보호되어야 하며 크기에 관계없이 항상 공유 메모리에 배열을 할당해야 합니다.

 
Dmitry Fedoseev # :

더블 x[268435448]; 일반 섹션에서 컴파일됩니다.

268435449 - 더 이상 컴파일되지 않음

그리고 OnStart() 스크립트에서 268435449가 컴파일되고 일반 섹션에 이 거대한 배열 x가 남습니다.

268435448*8= 2147483584 는 2개의 공연입니다.

***

그리고 함수의 한계는 다음과 같습니다. double x[268435456];

이것이 코드 분석기의 한계입니다. 결국, mql에 4GB, 6GB 또는 20GB 메모리를 할당하는 데 실제로 문제가 없습니다.

 
Vasiliy Sokolov # :

크기에 관계없이 항상 공유 메모리에 배열을 할당하십시오.

정적 배열을 사용하지 않습니까?