Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/18: Рейтинг темы: голосов - 18, средняя оценка - 4.50
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10

Работа с памятью внутри TJSONObject

05.01.2015, 20:13. Показов 3917. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам

Не по теме:

Тема вынесена из другой.


volvo, а где можно почитать про работу с памятью внутри TJSONObject? В справке негусто, а эти возвраты указателей с необходимостью явного каста... брр.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
05.01.2015, 20:13
Ответы с готовыми решениями:

Работа с TJSONObject и IdHTTP
Использую TJSONObject и IdHTTP, чтобы отправлять запрос к серверу, с данными JSON, вот код: TIdMultiPartFormDataStream *DataStream = new...

Нужна книга, где рассматриваются работа с прерываниями, указатели, работа с памятью, ассемблерные вставки
Привет всем! Подскажите, пожалуйста, хорошую книгу по C (именно C, не C++). Интересует работа с прерываниями, указатели, работа с памятью,...

TJSONObject
Возник еще вопрос по TJSONObject Получаю ответ в переменную Final {"response":}Нужно получить owner_id и id. Делаю так ...

5
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33404 / 21514 / 8236
Регистрация: 22.10.2011
Сообщений: 36,914
Записей в блоге: 12
05.01.2015, 20:15
Цитата Сообщение от BRcr Посмотреть сообщение
где можно почитать про работу с памятью внутри TJSONObject?
В исходниках, как всегда
1
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
05.01.2015, 21:38  [ТС]
Вот, допустим, есть реализация TJSONObject.
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
TJSONObject = class sealed(TJSONValue)
  public   
///...
    /// <summary> Parses a byte array and returns the JSON value from it.
    /// </summary>
    /// <remarks> 
    /// </remarks>
    /// <param name="Data">- byte array, not null</param>
    /// <param name="Offset">- offset from which the parsing starts</param>
    /// <param name="count">- buffer capacity</param>
    /// <param name="IsUTF8">- true if the Data should be treated as UTF-8. Optional, defaults to true</param>
    /// <returns>JSONValue - null if the parse fails</returns>
    class function ParseJSONValue(const Data: TArray<Byte>; const Offset: Integer; const Count: Integer; IsUTF8: Boolean = True): TJSONValue; overload; static;
 
///....
 
class function TJSONObject.ParseJSONValue(const Data: TArray<Byte>; const Offset: Integer;
                                          const Count: Integer; IsUTF8: Boolean): TJSONValue;
var
  Parent: TJSONArray;
  Answer: TJSONValue;
  Br: TJSONByteReader;
begin
  Parent := TJSONArray.Create;
  Answer := nil;
  Br := TJSONByteReader.Create(Data, Offset, Count, IsUTF8);
  try
    ConsumeWhitespaces(Br);
    if (ParseValue(Br, Parent) = Count) and (Parent.Size = 1) then
      Answer := Parent.Pop;
    Result := Answer;
  finally
    Parent.Free;
    Br.Free;
  end;
end;
Не пойму, возврат здесь вроде как по значению? Класс импортируется в плюсовую VCL, там возвращаемое значение уже указатель на TJSONValue:
C++
1
2
3
4
5
6
7
8
9
10
class PASCALIMPLEMENTATION TJSONObject/* [[sealed]] */ : public TJSONValue
{
    typedef TJSONValue inherited;
    
public:
    static int __fastcall HexToDecimal(const System::Byte Value);
    static TJSONValue* __fastcall ParseJSONValue(const System::DynamicArray<System::Byte> Data, const int Offset, bool IsUTF8 = true)/* overload */;
    static TJSONValue* __fastcall ParseJSONValue(const System::DynamicArray<System::Byte> Data, const int Offset, const int Count, bool IsUTF8 = true)/* overload */;
    static TJSONValue* __fastcall ParseJSONValue(const System::UnicodeString Data)/* overload */;
    static TJSONValue* __fastcall ParseJSONValue(const System::UTF8String Data)/* overload */;
Как именно мне понять, кто ответственен за освобождение памяти под возвращаемыми указателями? Здравый смысл твердит, что ответственен я, но в справке об этом ни слова, примеров нема, в нетах кто как делает, а знаний вывести искомое из приведенного выше кода как-то не хватает.
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33404 / 21514 / 8236
Регистрация: 22.10.2011
Сообщений: 36,914
Записей в блоге: 12
06.01.2015, 11:38
Цитата Сообщение от BRcr Посмотреть сообщение
Здравый смысл твердит, что ответственен я
Он Прав. Запуск Дельфийского кода:
Delphi
1
2
3
4
5
6
  Json := TJSONObject.ParseJSONValue(s) as TJSONObject;
  try
    // ...
  finally
    // Json.Free;
  end;
со взведенной переменной ReportMemoryLeaksOnShutdown выдает утечку памяти. Раскомментирование Free устраняет эту проблему.
Цитата Сообщение от BRcr Посмотреть сообщение
возврат здесь вроде как по значению?
В Дельфи вся работа с классами - по ссылке.
1
Марсианин)))
713 / 46 / 15
Регистрация: 18.07.2010
Сообщений: 637
06.01.2015, 13:56
Я извиняюсь, может не так вопрос понял, а если мы применим
C++
1
std::auto_ptr<TJSONObject>
То нам и освобождать не надо?
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
06.01.2015, 17:15  [ТС]
Dr.Xank, все верно, auto_ptr является одним из путей управления памятью. Вопрос изначально в том, кто должен заботится об освобождении памяти при работе с TJSONObject, то бишь необходимо ли ее самостоятельно освобождать?

Прямая проверка volvo показала, что надо. А мои прогулки по файлам DBX*.pas затянулись до анализа структуры парсера...
Получается, память выделяется конструктором копирования в строке Value := TJSONValue(FElements[0]); метода TJSONArray.Pop и результат возвращается по ссылке.
Помимо прочего пришел к выводу, что нафиг так рыться, быстрее сделать прямую проверку...
Еще, оказывается, есть сериализация на JSON - TJSONMarshal...

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

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class function TJSONObject.ParseJSONValue(const Data: TArray<Byte>; const Offset: Integer;
                                          const Count: Integer; IsUTF8: Boolean): TJSONValue;
var
  Parent: TJSONArray;
  Answer: TJSONValue;
  Br: TJSONByteReader;
begin
  Parent := TJSONArray.Create;
  Answer := nil;
// байт-ридер кушает входящую строку, убирает BOM и предоставляет парсеру TJSONObject.ParseValue удобный доступ к байтам текста
  Br := TJSONByteReader.Create(Data, Offset, Count, IsUTF8); 
  try
    ConsumeWhitespaces(Br);
// ParseValue разбирает строку на куски и в виде списка TDBXArrayList записывает внутрь TJSONArray Parent
    if (ParseValue(Br, Parent) = Count) and (Parent.Size = 1) then 
      Answer := Parent.Pop; // если парсинг успешен, метод Pop делает нам копию итогового результата
    Result := Answer;
  finally
    Parent.Free;
    Br.Free;
  end;
end;
Результат в итоге возвращается в виде копии объекта TJSONValue из первого элемента списка FElements: TDBXArrayList класса TJSONArray(Parent), хранящего уже распарсенную строку.
Pascal
1
2
3
4
5
6
7
8
9
10
11
function TJSONArray.Pop: TJSONValue;
var
  Value: TJSONValue;
begin
// делается копия элемента списка как TJSONValue, 
// но на самом деле внутри один из наследников TJSONValue в зависимости от результатов парсинга
// вот эта копия и возвращается в итоге под указателем, ее нам и освобождать потом
  Value := TJSONValue(FElements[0]); 
  FElements.RemoveAt(0);
  Result := Value;
end;
TJSONValue - абстрактный класс, без добавок наследующий от абстрактного же TJSONAncestor. От TJSONValue в свою очередь наследуются конкретные типы TJSONString(от этого происходит TJSONNumber как обертка для конвертации строки в число), TJSONObject, TJSONArray, на которых и построено хранение данных посредством внутренних списков TDBXArrayList(внутри просто список FList: TList<TObject>, в который помещаются данные как TJSONPair, TJSONString, TJSONArray и тд - на этом и стоит дерево парсинга) и массивов TStringBuilder(тип, промежуточный между просто массивом WideChar и типом String), а также вспомогательные TJSONTrue, TJSONNull, TJSONFalse. Из отдельных вспомогательных есть еще callback-делегаты, TJSONByteReader(хранящий непарсенную строку и делающий ее первичное форматирование), TJSONException, TJSONPair(TJSONString + TJSONValue), TJSONPairEnumerator...
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
06.01.2015, 17:15
Помогаю со студенческими работами здесь

Работа с памятью
Всем привет! Такая задача: открываю процесс в программе и я должен просканировать все его адреса памяти Делаю так: for i := $FFFFFFFF do ...

Работа с памятью
Есть приложение,в нем есть label'ы. Есть ли какая-нибудь возможность средствами C++ допустим, перевести эти контролы? Если есть - дайте...

Работа с памятью
Друзья, ассемблер только начал изучать. Ассемблер начал изучать недавно и сейчас передо мной стоит задача: 1. Необходимо получить из...

Работа с памятью
Всем добрый день. У меня появился такой вопрос: Предположим, есть такой код: AnotherObj GetAO() { SomethingObj A = new...

Работа с памятью
задача в следующем :нужно внедриться в процес и поочередно просматривать ячейки памяти записывая содержимое в переменную стринг. тогда...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Фото всей Земли с борта корабля Orion миссии Artemis II
kumehtar 04.04.2026
Это первое подобное фото сделанное человеком за 50 лет. Снимок называют новым вариантом легендарной фотографии «The Blue Marble» 1972 года, сделанной с борта корабля «Аполлон-17». Новое фото. . .
Вывод диалогового окна перед закрытием, если документ не проведён
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать программный контроль на предмет проведения документа. . .
Программный контроль заполнения реквизита табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать контроль заполнения реквизита "ПричинаСписания". . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
Вывод данных в справочнике через динамический список
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Программное заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru