Как вернуть объект из функции в Delphi, не вызывая нарушения прав доступа?

Подробнее о том, как это сделать, см. следующую ссылку:

Запустить и остановить агента репликации

Вышеупомянутая статья не отображается для предоставления информации об остановке агента распространения, это может быть достигнуто с помощью хранимых процедур, подробно описанных в ссылке ниже:

Запустить / остановить агент репликации SQL Server с помощью TSQL

13
задан Toon Krijthe 18 February 2009 в 18:52
поделиться

7 ответов

Как сказанный Обжимный пресс, Вы не можете освободить его; код, вызывающий функцию, которая возвращает объект, ответственен за уничтожение его.

Это - плохой дизайн кода, между прочим, поскольку он делает его путающий относительно того, кто выделяет и освобождает. Намного лучший способ сделать это состоял бы в том, чтобы сделать, чтобы вызывающая сторона создала объект и передала его в функции. Тем путем код, который создает его также, освобождает его. Что-то вроде этого:

var
  SL: TStringList;
begin
  SL := TStringList.Create;
  try
    ProcToFillStringList(SL);
    //Do something with populated list
  finally
    SL.Free;
  end;
end;

// Note I've made the parameter a TStrings and not a TStringList. This allows
// passing a TMemo.Lines or a TListBox or TComboBox Items as well.
procedure ProcToFillStringList(const SList: TStrings);
  // Do whatever populates the list with SList.Add()
end;

Теперь нет никакого беспорядка по тому, кто делает то, что - тот же код, который создает объект, ответственен за освобождение его. И код, IMO, является намного более четким считать и поддержать.

28
ответ дан Ken White 19 February 2009 в 04:52
поделиться
  • 1
    Ну, на самом деле это работало на меня. Я раньше mvn spring-boot:repackage и добрался Source must refer to an existing file. Используя mvn clean install spring-boot:repackage заставил его работать. – sjngm 7 June 2014 в 05:22

Простой ответ: Вы не можете. Почему Вы пытаетесь? Это, потому что Вы узнали, что необходимо освободить каждый объект, который Вы создаете в той же функции, в которой они создаются? Это обычно корректно, но не всегда, и это - одно из исключений из правила. Лучший способ поместить его состоит в том, что каждый объект должен быть освобожден его владельцем.

, Если у Вас есть функция, которая генерирует объект, как этот, но затем передает его на другую функцию, он не берет владение объекта. Удалите вызов, чтобы освободить и зарегистрировать его, таким образом, Вы (и кто-либо еще, кто использует эту функцию) поймете, что это создает новый объект, из которого код, который называет его, должен взять владение.

6
ответ дан Mason Wheeler 19 February 2009 в 04:52
поделиться

, Как я могу возвратить TStringList и все еще освободить его в локальной функции?

Вы не можете. При освобождении его в локальной функции Вы не можете использовать возвращаемое значение. Результат и vStrList указывают на тот же объект TStringList в памяти. TStringList является классом, и

Result := vStrList

поэтому не копирует список строк, но только копирует ссылку.

Так, вместо этого необходимо освободить список строк в контексте вызова после того, как Вы будете сделаны, работая с ним или передадите список строк в качестве параметра Вашей функции как это

procedure FuncStringList (StringList : TStringList);

и позволите коду вызова создать и освободить список строк. Как указано другими ответами, это - предпочтительный путь, так как он делает владение очень ясным.

27
ответ дан jpfollenius 19 February 2009 в 04:52
поделиться

Не освобождайте объект, прежде чем Вы будете сделаны, вызывая методы на нем. Вы в настоящее время вызываете Метод счета для уничтоженного объекта, следовательно ошибка.

, Почему Вы не создаете список строк в функции вызова и передаете ее ссылку на метод, который заполняет его? Или сделайте список строк членом класса и освободите его при освобождении класса, который владеет им?

0
ответ дан SteinNorheim 19 February 2009 в 04:52
поделиться
  • 1
    You' приветствие ре, счастливое помочь другим, которые сталкиваются с теми же проблемами как я:) don' t нравится быть DenverCoder9: D – r1pp3rj4ck 8 May 2014 в 18:09

Вы просто не можете освободить что-то и затем ожидать ссылаться на него позже. Это - неправильный путь. У Вас есть две основных опции:

  • не называют свободными, и делают вызывающую сторону ответственной за избавление от объекта
  • , Сделали, чтобы вызывающая сторона передала в объекте так, чтобы это было ответственно, и за Создать и за Свободный

первая опция кажется более простой, сохраняет интерфейс к функции меньшим, и т.д. Вторая опция делает использование менее подверженным ошибкам, потому что это интуитивно вызывающей стороне, что это ответственно за управление объектом.

2
ответ дан dwc 19 February 2009 в 04:52
поделиться
  • 1
    большое спасибо за " jar" проблема, Вы сделали мой вечер! – mishka 8 May 2014 в 05:52

Другая возможность состоит в том, чтобы использовать динамический массив вместо TStringList. Так как массивы являются считаемой ссылкой, Вы никогда не должны будете волноваться об освобождении ее.

0
ответ дан smo 19 February 2009 в 04:52
поделиться

Политика, которую я имею с такими ситуациями, состоит в том, чтобы передать stringlist содержание через текстовое свойство и просто передать строку, возвращенную к функции. Таким образом, там не является никакая потребность обсудить, кто выпускает кто. Конечно, необходимо сделать немного больше кодирования, но это более безопасно. Примером является адаптация одной Ken White:

var
  SL: TStringList;
  Aux: String;
begin
  SL := TStringList.Create;
  try
    SL.Text := ProcToFillStringList;
    //Do something with populated list
  finally
    SL.Free;
  end;
end;

 // It receives a default param, in the case you have to deal with 
 // StringList with some previous content    
 function ProcToFillStringList(SListContent: String = ''):String;
 // Do the stuff you need to do with the content
end;

исключение - когда все, что Вы имеете, является объектом и нет никакого способа получить содержание на нем через безопасный тип (в этом случае, строки); тогда я следую за идеей Ken White.

0
ответ дан Fabricio Araujo 19 February 2009 в 04:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: