Если выставить позицию за "правую границу" файла (больше, чем размер файла), то последующая запись в файл будет будет произведена не с конца файла, а с выставленной позиции. При этом между предыдущим концом файла и выставленной позицией будут записаны неопределенные значения...
Что будет быстрее-много текстовых файлов с одной строкой или один файл с большим количеством строк?
Зависит от конкретной реализации алгоритма и задачи, которую нужно решить. Возможно в Вашем случае будет быстрее первый вариант, но о производительности я бы на Вашем месте пока не задумывался.
Nikolay Gaylis:
Подскажите пожалуйста как перенести курсор ,скажем на 7 строчку в текстовом документе,для извлечения подстроки уже с этой позиции...
Читайте стандартную документацию. Раздел "Файловые операции". Например можно построчно считать файл с помощью FileReadString, пример прямо из документации:
//--- покажем окно входных параметров при запуске скрипта #property script_show_inputs//--- параметры для чтения данных inputstring InpFileName="Trend.bin"; // имя файла inputstring InpDirectoryName="Data"; // имя директории //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ voidOnStart()
{
//--- откроем файл ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_BIN|FILE_ANSI);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("Файл %s открыт для чтения",InpFileName);
PrintFormat("Путь к файлу: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
//--- вспомогательные переменные int str_size;
string str;
//--- прочитаем данные из файла while(!FileIsEnding(file_handle))
{
//--- узнаем сколько символов использовано для записи времени
str_size=FileReadInteger(file_handle,INT_VALUE);
//--- прочитаем строку
str=FileReadString(file_handle,str_size);
//--- распечатаем строку PrintFormat(str);
}
//--- закроем файл FileClose(file_handle);
PrintFormat("Данные прочитаны, файл %s закрыт",InpFileName);
}
elsePrintFormat("Не удалось открыть файл %s, Код ошибки = %d",InpFileName,GetLastError());
}
Значит накосячили с CArrayObj. Вместо: CArrayObj test_objects; Написали: CArrayObj* test_objects, а диструктор для него забыли сделать; Возможно неправильно сконфигурировали модель памяти по работе с CArrayObj. Может просто с указателями перемудрили. Диагноз однозначный: использование указателей там, где они не нужны, часто приводит к утечкам.
Есть функция в каком-то классе. В ней я объявляю массив объектов CArrayObj. В него добавляю глобальные объекты класса. Закончилась функция, сам массив объектов не нужен. Объекты, разумеется, нужны.
Если я создаю массив как указатель CArrayObj *test_objects, то потом получаю undeleted objects в логе, что приведет в конце концов к ошибке out of memory.
Если я объявляю массив так CArrayObj test_objects, добавляю в него объекты, то получается по окончании действия функции и объекты станут недоступны, т.к. массив с объектами как бы удалился...
Если я объявляю массив так CArrayObj test_objects, добавляю в него объекты, то получается по окончании действия функции и объекты станут недоступны, т.к. массив с объектами как бы удалился...
Все правильно, потому что в этом случае вы размещаете CArrayObj test_objects на стеке, а адресном пространстве функции. Когда происходит выход из функции, адресное пространство функции затирается, включая и Ваш CArrayObj test_objects.
Juer:
Закончилась функция, сам массив объектов не нужен. Объекты, разумеется, нужны.
Запомните раз и навсегда - если нужны объекты внутри CArrayObj, то и сам CArrayObj нужен. CArrayObj обязательная упаковка. Без него никак, точка.
Juer:
Если я создаю массив как указатель CArrayObj *test_objects, то потом получаю undeleted objects в логе, что приведет в конце концов к ошибке out of memory.
В этом случае создается указатель на некий объект CArrayObj в куче. Куча - это сегмент памяти адресного пространства программы, выделение и удаление памяти в которой происходит вручную, с помощью соответствующих операторов new и delete. Это значит что если Вы пишите new, то обязательно где-то должен быть зеркальный близнец delete. При том new и delete могут располагаться в разных частях программы, например в разных методах:
CArrayObj* foo_create()
{
//-- Выделили память в куче, под объект CArrayObj и создали егоCArrayObj* obj_array = new CArrayObj();//-- Заполняем obj_array полезной нагрузкой
obj_array.Add(new CItem());
...
...
//-- Выходим из функции. При этом объект CArrayObj и память под него не затирается.//-- Он по-прежнему доступен по указателю. Единственный указатель, который ведет//-- к нему это obj_array. Возвращаем его вызвавшей функцииreturn obj_array;
}
void foo_analize()
{
//-- Получили указатель obj_array из foo_create//-- здесь он будет под именем obj_analize
CArrayObj* obj_analize = foo_create();
//-- Проанализировали объекты внутри obj_analize
...
...
...
//-- Здесь объект obj_analize и его элементы больше не нужены//-- Удаляем объект и все его элементы. Отдельно удалять элементы//-- не нужно. CArrayObj сделает все автоматически.delete obj_analize;
}
Если и после вызова foo_analize объекты по-прежнему нужны, то оператор delete можно перенести в другое место, при достижении которого объекты гарантированно становятся ну нужными. Таким универсальным местом может быть OnDeinit например, который вызывается перед закрытием программы.
Запомните главное, если есть оператор new, всегда должен быть оператор delete для него. В противном случае будут утечки памяти. Операторы new и delete работающие с одним и тем же объектом не обязательно должны располагаться в одном методе "рядом". Delete может быть где угодно далеко от места выделения памяти, главное, что бы у delete была ссылка на выделенный объект в куче.
** Замечу что сказанное хотя и является верным, лучше избегать подобных конструкций, т.к. всегда приходится очень внимательно смотреть где и при каких обстоятельствах вызывать оператор delete, что не всегда является очевидным. Вместо этого нужно просто научиться использовать классы. Класс позволяет автоматически размешать и удалять объекты на куче, без использования операторов new и delete:
class CMyCalculation
{
private:
//-- Содержит объекты, над которыми нужно провести некоторые мат. операции
CArrayObj m_obj_array;
void CreateObj();
public:
void Calc();
};
//-- Считает массив объектов CArrayObjvoid CMyCalculation::Calc()
{
//-- Если объектов нет, создаем их
if(m_obj_array.Total() == 0)
CreateObj();
//-- Рассчитываем нужные нам значения на данных
for(int i = 0; i < m_obj_array.Total(); i++)
{
CItem* item = m_obj_array.At(i);
//-- обсчитывает item как нам нужно
...
...
}
}
//-- Создает массив объектов CItemvoid CMyCalculation::CreateObj()
{
m_obj_array.Add(new CItem());
m_obj_array.Add(new CItem());
...
...
}
Данный класс не содержит указателей в явном виде. Значит не нужно использовать как new так и delete. После выхода из программы, класс освободит все объекты CItem и CArrayObj автоматически, что здорово упрощает жизнь разработчику.
Все правильно, потому что в этом случае вы размещаете CArrayObj test_objects на стеке, а адресном пространстве функции. Когда происходит выход из функции, адресное пространство функции затирается, включая и Ваш CArrayObj test_objects.
Запомните раз и навсегда - если нужны объекты внутри CArrayObj, то и сам CArrayObj нужен. CArrayObj обязательная упаковка. Без него никак, точка.
В этом случае создается указатель на некий объект CArrayObj в куче. Куча - это сегмент памяти адресного пространства программы, выделение и удаление памяти в которой происходит вручную, с помощью соответствующих операторов new и delete. Это значит что если Вы пишите new, то обязательно где-то должен быть зеркальный близнец delete. При том new и delete могут располагаться в разных частях программы, например в разных методах:
Если и после вызова foo_analize объекты по-прежнему нужны, то оператор delete можно перенести в другое место, при достижении которого объекты гарантированно становятся ну нужными. Таким универсальным местом может быть OnDeinit например, который вызывается перед закрытием программы.
Запомните главное, если есть оператор new, всегда должен быть оператор delete для него. В противном случае будут утечки памяти. Операторы new и delete работающие с одним и тем же объектом не обязательно должны располагаться в одном методе "рядом". Delete может быть где угодно далеко от места выделения памяти, главное, что бы у delete была ссылка на выделенный объект в куче.
** Замечу что сказанное хотя и является верным, лучше избегать подобных конструкций, т.к. всегда приходится очень внимательно смотреть где и при каких обстоятельствах вызывать оператор delete, что не всегда является очевидным. Вместо этого нужно просто научиться использовать классы. Класс позволяет автоматически размешать и удалять объекты на куче, без использования операторов new и delete:
Данный класс не содержит указателей в явном виде. Значит не нужно использовать как new так и delete. После выхода из программы, класс освободит все объекты CItem и CArrayObj автоматически, что здорово упрощает жизнь разработчику.
Спасибо. Только что-то на мой конкретно вопрос я не нашёл ответа. Куда мне delete поместить, если я объявляю указатель. Повторяю объект CArrayObj объявляется в функции... как я могу его удалять в Deinit()?
Но предварительно я решил проблему вот так. Перед завершением функции:
Спасибо. Только что-то на мой конкретно вопрос я не нашёл ответа. Куда мне delete поместить, если я объявляю указатель. Повторяю объект CArrayObj объявляется в функции... как я могу его удалять в Deinit()?
Здесь не клуб телепатов. Свой код Вы не приложили, поэтому о том, где размещать delete, думайте сами.
Здравствуйте. Помогите, пожалуйста, я настроил индикатор чтобы он отправлял сообщения по достижению цены 400 пунктов, но по достижению этих условий мне отправляется куча сообщений. Как сделать так, чтобы отправлялось только одно. Спасибо!
Для авторизации и пользования сайтом MQL5.com необходимо разрешить использование файлов Сookie.
Пожалуйста, включите в вашем браузере данную настройку, иначе вы не сможете авторизоваться.
Вы вошли в аккаунт. Двухфакторная аутентификация отключена. Настройте её заново и отсканируйте новый QR-код или продолжите с отключённой двухфакторной аутентификацией.
Здравствуйте!
Подскажите пожалуйста как перенести курсор ,скажем на 7 строчку в текстовом документе,для извлечения подстроки уже с этой позиции...
Что будет быстрее-много текстовых файлов с одной строкой или один файл с большим количеством строк?
Нужно знать сколько байт в одной строке и переместить указатель на 6 таких значений от начала файла.
Здравствуйте!
Что будет быстрее-много текстовых файлов с одной строкой или один файл с большим количеством строк?
Зависит от конкретной реализации алгоритма и задачи, которую нужно решить. Возможно в Вашем случае будет быстрее первый вариант, но о производительности я бы на Вашем месте пока не задумывался.
Подскажите пожалуйста как перенести курсор ,скажем на 7 строчку в текстовом документе,для извлечения подстроки уже с этой позиции...
Читайте стандартную документацию. Раздел "Файловые операции". Например можно построчно считать файл с помощью FileReadString, пример прямо из документации:
Подскажите, как конвертировать значение нажатия кнопки мыши на графике в значение цены или наоборот.
Подскажите, как конвертировать значение нажатия кнопки мыши на графике в значение цены или наоборот.
Используйте функцию ChartXYToTimePrice. См. раздел "Операции с графиками" в документации.
Используйте функцию ChartXYToTimePrice. См. раздел "Операции с графиками" в документации.
Благодарю.
Значит накосячили с CArrayObj. Вместо: CArrayObj test_objects; Написали: CArrayObj* test_objects, а диструктор для него забыли сделать; Возможно неправильно сконфигурировали модель памяти по работе с CArrayObj. Может просто с указателями перемудрили. Диагноз однозначный: использование указателей там, где они не нужны, часто приводит к утечкам.
Есть функция в каком-то классе. В ней я объявляю массив объектов CArrayObj. В него добавляю глобальные объекты класса. Закончилась функция, сам массив объектов не нужен. Объекты, разумеется, нужны.
Если я создаю массив как указатель CArrayObj *test_objects, то потом получаю undeleted objects в логе, что приведет в конце концов к ошибке out of memory.
Если я объявляю массив так CArrayObj test_objects, добавляю в него объекты, то получается по окончании действия функции и объекты станут недоступны, т.к. массив с объектами как бы удалился...
Если я объявляю массив так CArrayObj test_objects, добавляю в него объекты, то получается по окончании действия функции и объекты станут недоступны, т.к. массив с объектами как бы удалился...
Все правильно, потому что в этом случае вы размещаете CArrayObj test_objects на стеке, а адресном пространстве функции. Когда происходит выход из функции, адресное пространство функции затирается, включая и Ваш CArrayObj test_objects.
Закончилась функция, сам массив объектов не нужен. Объекты, разумеется, нужны.
Запомните раз и навсегда - если нужны объекты внутри CArrayObj, то и сам CArrayObj нужен. CArrayObj обязательная упаковка. Без него никак, точка.
Если я создаю массив как указатель CArrayObj *test_objects, то потом получаю undeleted objects в логе, что приведет в конце концов к ошибке out of memory.
В этом случае создается указатель на некий объект CArrayObj в куче. Куча - это сегмент памяти адресного пространства программы, выделение и удаление памяти в которой происходит вручную, с помощью соответствующих операторов new и delete. Это значит что если Вы пишите new, то обязательно где-то должен быть зеркальный близнец delete. При том new и delete могут располагаться в разных частях программы, например в разных методах:
CArrayObj* foo_create() { //-- Выделили память в куче, под объект CArrayObj и создали его CArrayObj* obj_array = new CArrayObj(); //-- Заполняем obj_array полезной нагрузкой obj_array.Add(new CItem()); ... ... //-- Выходим из функции. При этом объект CArrayObj и память под него не затирается. //-- Он по-прежнему доступен по указателю. Единственный указатель, который ведет //-- к нему это obj_array. Возвращаем его вызвавшей функции return obj_array; } void foo_analize() { //-- Получили указатель obj_array из foo_create //-- здесь он будет под именем obj_analize CArrayObj* obj_analize = foo_create(); //-- Проанализировали объекты внутри obj_analize ... ... ... //-- Здесь объект obj_analize и его элементы больше не нужены //-- Удаляем объект и все его элементы. Отдельно удалять элементы //-- не нужно. CArrayObj сделает все автоматически. delete obj_analize; }Если и после вызова foo_analize объекты по-прежнему нужны, то оператор delete можно перенести в другое место, при достижении которого объекты гарантированно становятся ну нужными. Таким универсальным местом может быть OnDeinit например, который вызывается перед закрытием программы.
Запомните главное, если есть оператор new, всегда должен быть оператор delete для него. В противном случае будут утечки памяти. Операторы new и delete работающие с одним и тем же объектом не обязательно должны располагаться в одном методе "рядом". Delete может быть где угодно далеко от места выделения памяти, главное, что бы у delete была ссылка на выделенный объект в куче.
** Замечу что сказанное хотя и является верным, лучше избегать подобных конструкций, т.к. всегда приходится очень внимательно смотреть где и при каких обстоятельствах вызывать оператор delete, что не всегда является очевидным. Вместо этого нужно просто научиться использовать классы. Класс позволяет автоматически размешать и удалять объекты на куче, без использования операторов new и delete:
Данный класс не содержит указателей в явном виде. Значит не нужно использовать как new так и delete. После выхода из программы, класс освободит все объекты CItem и CArrayObj автоматически, что здорово упрощает жизнь разработчику.
Все правильно, потому что в этом случае вы размещаете CArrayObj test_objects на стеке, а адресном пространстве функции. Когда происходит выход из функции, адресное пространство функции затирается, включая и Ваш CArrayObj test_objects.
Запомните раз и навсегда - если нужны объекты внутри CArrayObj, то и сам CArrayObj нужен. CArrayObj обязательная упаковка. Без него никак, точка.
В этом случае создается указатель на некий объект CArrayObj в куче. Куча - это сегмент памяти адресного пространства программы, выделение и удаление памяти в которой происходит вручную, с помощью соответствующих операторов new и delete. Это значит что если Вы пишите new, то обязательно где-то должен быть зеркальный близнец delete. При том new и delete могут располагаться в разных частях программы, например в разных методах:
Если и после вызова foo_analize объекты по-прежнему нужны, то оператор delete можно перенести в другое место, при достижении которого объекты гарантированно становятся ну нужными. Таким универсальным местом может быть OnDeinit например, который вызывается перед закрытием программы.
Запомните главное, если есть оператор new, всегда должен быть оператор delete для него. В противном случае будут утечки памяти. Операторы new и delete работающие с одним и тем же объектом не обязательно должны располагаться в одном методе "рядом". Delete может быть где угодно далеко от места выделения памяти, главное, что бы у delete была ссылка на выделенный объект в куче.
** Замечу что сказанное хотя и является верным, лучше избегать подобных конструкций, т.к. всегда приходится очень внимательно смотреть где и при каких обстоятельствах вызывать оператор delete, что не всегда является очевидным. Вместо этого нужно просто научиться использовать классы. Класс позволяет автоматически размешать и удалять объекты на куче, без использования операторов new и delete:
Данный класс не содержит указателей в явном виде. Значит не нужно использовать как new так и delete. После выхода из программы, класс освободит все объекты CItem и CArrayObj автоматически, что здорово упрощает жизнь разработчику.
Спасибо. Только что-то на мой конкретно вопрос я не нашёл ответа. Куда мне delete поместить, если я объявляю указатель. Повторяю объект CArrayObj объявляется в функции... как я могу его удалять в Deinit()?
Но предварительно я решил проблему вот так. Перед завершением функции:
CClass func() { CArrayObj test_objects; test_objects.Add(m_object1); test_objects.Add(m_object2); .... for(int i=0;i<test_objects.Total();i++) { test_objects.Detach(i); } return .. }Спасибо. Только что-то на мой конкретно вопрос я не нашёл ответа. Куда мне delete поместить, если я объявляю указатель. Повторяю объект CArrayObj объявляется в функции... как я могу его удалять в Deinit()?
Здесь не клуб телепатов. Свой код Вы не приложили, поэтому о том, где размещать delete, думайте сами.
CClass func() { CArrayObj test_objects; test_objects.Add(m_object1); test_objects.Add(m_object2); .... for(int i=0;i<test_objects.Total();i++) { test_objects.Detach(i); } return .. }Неправильно.