mql5语言的特点、微妙之处以及技巧 - 页 217

 
fxsaber #:
现在(b3110)如何将一个复杂的结构归零?

具有归零功能的构造函数。

而如果你想在进度中归零,还有一个额外的方法可以做到。

struct MqlTick2 : private MqlTick
{
        string Str; // С этой строкой не обнулить.

        MqlTick2()
        {
                Init();
        }
        void Init()
        {
                Str = NULL;
        };
};

void OnStart()
{
        MqlTick2 tick;
        Print( tick.Str );  // NULL
        tick.Str = "123";
        Print( tick.Str );  // "123"
        tick.Init();
        Print( tick.Str );  // NULL
}
 
Andrey Khatimlianskii #:

具有归零功能的构造函数。

如果你想在工作期间将其归零,那么可以采用其他方法。

我希望有一个通用的方法,就像ZeroMemory曾经允许的那样。

 
A100 #:

考虑到我已经改变了--现在我检查第一项的x[i].i == 0(以前的条件是x[i].x == 0.0)。

结果:假

而有了ZeroMemory--真的。

谢谢,修好了。

 

关于交易、自动交易系统和交易策略测试的论坛

mql5的特殊性,技巧和窍门

mktr8591, 2021.08.12 19:43

我设置了一个待定的限制。然后,我手动和通过脚本改变它,ORDER_TIME_SETUP 就会改变。

变化的例子。

设置日志。

QG      0       22:00:02.376    Trades  '93912': accepted buy limit 13.1 AUDUSD at 0.71897 tp: 0.71927
IS      0       22:00:02.378    Trades  '93912': order #5774292 buy limit 13.1 / 13.1 AUDUSD at 0.71897 done in 33.487 ms

ORDER_TIME_SETUP被改变。错误?

 
fxsaber #:

我希望有一种通用的方式,就像ZeroMemory曾经允许的那样。

而谁将释放字符串中的缓冲区?ZeroMemory本质上是一个类似的东西。

https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/aa366920(v=vs.85)

将不会调用任何析构器。相应地,缓冲区指针将在字符串中被清除,而缓冲区本身将被泄露。与记忆有关的直接工作就像一个雷区--如果你失去警惕性,那就是了)))。

下面是你的案例中的一个泄漏的例子。

#include <iostream>
#include <string>
#include <cstring>

int main()
{
    std::string example{"Leaked memory!!!"};
    std::cout<<"First: "<<example<<std::endl;
    const char* data=example.data();
    std::memset(&example,0,sizeof(example));
    std::cout<<"Second: "<<example<<std::endl;
    std::cout<<"Third: "<<data<<std::endl;
    return 0;
}
First: Leaked memory!!!
Second: 
Third: Leaked memory!!!

该对象不再拥有一个指向缓冲区的指针,而缓冲区本身也 "泄露 "了。

PS。他妈的不通过memset和ZeroMemory将POD类型归零

 
Vladimir Simakov #:

PS。它不是通过memset和ZeroMemory 进行的POD类型归零。

没有测试过,但我认为字符串缓冲区被清零了。

 
fxsaber #:

我没有检查过,但我认为字符串缓冲区正在被重置。

为什么会重置?)

#import "CPPTestDll.dll"
        long GetAddress(string &ptr);
        string Text(long data);
#import

struct A{
   string a;
   int b;
};

void OnStart()
{
  string t1="Test";
  string t2="text";
  Print(t1);
  Print(t2);
  A a={"",8};
  a.a+=t1+" "+t2;
  long ptr=GetAddress(a.a);
  Print(a.a," | ",a.b);
  Print(Text(ptr));
  Print("-------------------------");
  ZeroMemory(a);
  Print(a.a," | ",a.b);
  Print(Text(ptr));
}


2021.11.28 14:49:29.354 test (EURUSD,H4)        Test
2021.11.28 14:49:29.354 test (EURUSD,H4)        text
2021.11.28 14:49:29.354 test (EURUSD,H4)        Test text | 8
2021.11.28 14:49:29.354 test (EURUSD,H4)        Test text
2021.11.28 14:49:29.354 test (EURUSD,H4)        -------------------------
2021.11.28 14:49:29.354 test (EURUSD,H4)         | 0
2021.11.28 14:49:29.354 test (EURUSD,H4)        Test text

这是 它应该有的成熟度))))。

UPD: t1, t2与它们的输出,这样编译器就不会对整个事情进行过度优化)

UPD2: 他们可以为缓冲区调用delete,但我不知道在字符串在结构内的情况下如何做。

UPD3: 虽然它写在帮助中,但它是亲自调用的,所以它应该释放缓冲区,我希望,通过指向释放的内存的指针已经读取数据。

附加的文件:
 
Vladimir Simakov #:

他为什么要重置?)

最好是能看到

Print(GetAddress(a.a));

之前和之后。

 
fxsaber #:

最好是能看到

之前和之后。

应该是这样的。在第一种情况下是内存地址,在第二种情况下是0

 
Vladimir Simakov #:

他为什么要重置?)


这里的一切都很成熟,因为它应该是这样的))))。

UPD: t1, t2与它们的输出,这样编译器就不会对整个事情过度优化)

UPD2: 他们可以为缓冲区调用delete,但我不知道在字符串在结构内的情况下如何做

UPD3:虽然是写在帮助中,但个人认为是为它而叫的,这意味着缓冲区应该被释放,我希望它已经通过指针释放了内存。

原则上,那里的一切都应该是非常微不足道的实现)