Передача по ссылке или по значению

Тема в разделе "Arduino & Shields", создана пользователем Hadgehogs, 19 сен 2019.

  1. Hadgehogs

    Hadgehogs Нуб

    Дня доброго.
    Arduino UNO
    Допустим, есть строка в 150 символов.
    Когда я вывожу ее в Сериал монитор из основной процедуры - она нормально отображается. (время + строка)
    Когда я вывожу ее в Сериал монитор из вложенной процедуры -в монитор выводиться пустая строка (время + пусто)

    Вложенная процедура

    void AddDebug(String Value, bool AddSuffix = true)
    {
    if (UseDebug == false)
    {
    return;
    }
    Serial.print(Value); //Тут нет UseDebug =true
    if (AddSuffix)
    {
    Serial.println("");
    }
    }

    Основная процедура:
    Serial.print(TestMessage); // Тут выводится
    AddDebug(TestMessage);

    Вопрос - void AddDebug(String Value) передается как указатель на TestMessage или как его копия. Подозреваю, что может не хватать памяти:

    Скетч использует 16630 байт (51%) памяти устройства. Всего доступно 32256 байт.
    Глобальные переменные используют 1152 байт (56%) динамической памяти, оставляя 896 байт для локальных переменных. Максимум: 2048 байт.
     
  2. Hadgehogs

    Hadgehogs Нуб

    String - это AnsiString или UnicodeString ?
     
  3. Hadgehogs

    Hadgehogs Нуб

    А то мы пришли из Дельфи, где все мило и пушисто со строками.
     
  4. NikitOS

    NikitOS Король шутов Администратор

    А может прочитаем то, что написано в верху страницы, под лого?
     
    issaom нравится это.
  5. DetSimen

    DetSimen Guest

    передавай строку по ссылке String &Value, иначе она каждый раз будет копироваться и работать внутри функции ты будешь с копией. А если памяти не хватает - то с пустым объектом.

    ты же, надеюсь в Delphi строки и дин. массивы константой передаешь, чтоб они не копировались?
    так: MyFunc(const AValue: string) если менять не нада и MyFunc(var AValue: string) если надо
    или нет?
     
    Asper Daffy и issaom нравится это.
  6. DetSimen

    DetSimen Guest

    String - это массив char, который 1 байт размером. Если хошь, можешь написать String для wchar_t, но, думаю

    dobro.png
     
    Последнее редактирование модератором: 19 сен 2019
    issaom нравится это.
  7. Hadgehogs

    Hadgehogs Нуб

    В Дельфях строка передается по ссылке.
    Вернее не так. В Дельфях - String - это объект с контролем ссылок и контролем изменения. При передаче в функцию, при переприсвоении одной переменной другой - передается ссылка. Как только переданный параметр изменится - создается копия.

    var
    tmp1, tmp2:String;

    begin
    tmp1:='Мама мыла раму';
    tmp2:=tmp1;
    ShowMessage(tmp2); // данные возьмутся из области памяти tmp1

    tmp2:=tmp2+""; // только тут в tmp2 создастся копия.

    Аналогично с вызовом в процедурах.
     
  8. DetSimen

    DetSimen Guest

    Ох, как ты неправ. Ну да ладно
     
    Asper Daffy нравится это.
  9. Hadgehogs

    Hadgehogs Нуб

    Раздел String. Строки здорового человека. Ребята из Embarcadero просто взяли и впилили универсальный механизм, который прозрачно работает с ушлепскими C-строками, с BSTR строками и строками от старых Дельфи. Это лучшая реализация строк, что я видел в ЯП, которые могут в указатели.

    https://www.transl-gunsmoker.ru/2009/09/pchars.html
     
  10. Hadgehogs

    Hadgehogs Нуб

    "передавай строку по ссылке String &Value,"
    Спасибо большое за ответ.

    Можно как то узнать оставшуюся динамическую память ?
     
  11. Asper Daffy

    Asper Daffy Иксперд

    Конечно копия. Хочешь передавать что-то другое, так и пиши (например void AddDebug(String & Value) - передача по ссылке )
    А проверить? Что-то с религией? :)
     
  12. Asper Daffy

    Asper Daffy Иксперд

    И фрагментацию тоже. Вот тут, в конце стартового поста.
     
    DetSimen нравится это.
  13. Hadgehogs

    Hadgehogs Нуб

    еще и фрагментация!
    Эхх, вот что бывает, когда приходишь из приложений, спокойно съедающих 5-ок Гб памяти за 1 серверный вызов в узкий мирок 2 Кб ОЗУ.
     
  14. А это уже и есть мастерство программирования - писать оптимизированный код ;)
     
  15. Hadgehogs

    Hadgehogs Нуб

    Нуууу, у нас тоже бывают моменты, когда блока 200-300 Мб на строку в памяти может не найтись при разборе какого - нибудь txt.
     
  16. Asper Daffy

    Asper Daffy Иксперд

    Да, не за что. Пожалуйста.
     
    DetSimen нравится это.
  17. Hadgehogs

    Hadgehogs Нуб

    Хорошо, что я столкнулся с этим до того, как ко мне приехала Arduion DUO, иначе бы и не узнал про этот момент.
     
  18. DetSimen

    DetSimen Guest

    Вот смари, чотамкак в Delphi.

    1. передача строки по значению. MyProc(AString: string) Здесь, в процедуру хоть и передаёцца адрес строки, но в куче сразу отводится память, содержимое переданной строки сразу же копируется в новую, и дальше ты уже работаешь с ней. Можешь менять в этой строке все что угодно, на первоначальной это не отразится никак, это уже разные строки, с разными адресами.

    2. Передача указателя на константную строку MyProc(const AString: string). Здесь тоже передается адрес, но ты обещаешь компилятору. что переданную строку ты изменять не будешь, поэтому копия строки НЕ делается и работа с ней происходит быстрее, но компилятор нимательна следит за твоими ручками, чтоб первозданная строка не менялась.

    3. Передача по ссылке MyProc(var AString: string) Передается, грубо говоря, аналог ссылки С++, (или константный указатель на неконстантную строку). Копия строки опять же в куче НЕ делается и все изменения которые ты вносишь в переданную строку - тут же отражается на первоначальной, они одинаковы, референсная ссылка на использование первоначальной строки даже не инкрементируется.

    в С++ практически то же самое, только строка, переданная по значению: myFunc(String str) копируется не в кучу а на стек и автоматически уничтожается при выходе из функции. Любые изменения, сделанные в этой строке, никак не отражаются на первоначальной. Но память жрёть, во-первых на вызов конструктора String и на копирование в нее данных переданной. AsperDaffy дал тебе хорошую ссылку на использование памяти в С++, прочти. Оно, хоть и похоже на Delphi, вопщих чертах, но сильно отличаеца в нюансах, будет полезно.
     
    Daniil, Asper Daffy, KindMan и ещё 1-му нравится это.
  19. Hadgehogs

    Hadgehogs Нуб

    Код (Text):
    procedure TForm1.Button1Click(Sender: TObject);
    var
    value:String;
    Addr:Pointer;
    begin
    value:='Money for nothing!';
    Addr:=Pchar(value);
    memo1.Lines.Add('Адрес String основной процедуры: '+inttostr(THandle(Addr)));
    Test(value);
    end;

    procedure TForm1.Test(value: String);
    var
    Addr:Pointer;
    begin
    Addr:=Pchar(value);
    memo1.Lines.Add('Адрес String вложенной процедуры: '+inttostr(THandle(Addr)));
    value:=value+'!';
    Addr:=Pchar(value);
    memo1.Lines.Add('Адрес String вложенной процедуры после изменения: '+inttostr(THandle(Addr)));
    end;
    Адрес String основной процедуры: 6299400
    Адрес String вложенной процедуры: 6299400
    Адрес String вложенной процедуры после изменения: 82268564
     
  20. Hadgehogs

    Hadgehogs Нуб

    String - это особая штука в Delphi 2009 и выше. Это объект.