Проблемы с сортировкой

Почему п…ец…? Вроде как по логике все верно… Массив указателей это только указатели , которые указывают на место в памяти, но так как я не инициализирую массив при обьявлении , по сути память под этот содержимое этого массива не выделена . Таким образом чтобы мне добавить туда новую строчку , мне надо выделить под нее место в куче, забрать указатель на него и положить его в мой массив указателей… Разве не логично… или я чтото упускаю ,
или Вы имеете ввиду , что я malloc и new char считаю по сути одним и тем же…? Ну да по сути они конечно одно и тоже , но я уже понял что различия довольно существенны и в моем случае проще работать с new , хотя это не исключает того , что с помощью malloc мою задачу тоже можно решить , поэтому я пытаюсь разобраться и с тем и с тем … Хотя для начало я не правильно выбрал приорритет … malloc действительно сложнее , так как там надо ручками делать больше (прав был SADMAN) надо аккуратнее…

Насчет проверки … да ночью я уже понял , что ступил не проверяя что мне возращает
malloc ,обнаружив , что он пытается выделить мне место на нижней границе памяти , причем
если верить адресам пересекается со стеком , что соответственно рушит мой код…

Я неправильно понял смысл Вашего вопроса … извините… Решив , что мне надо вызвать сортировку раз в 2-3 -4 месяца, причем в самом начале работы оборудования , я посчитал , что гораздо проще создать массив указателей , который займет 60 байт , заполнить массив в памяти отсоортировать его запихать обратно в еепром , а после этого освободить занятое под массив пространство , т образом даже если будет занято 600 символов, то к моменту выполнения основной программы все равно останется 60 , а оставшиеся 540 я смогу использовать для своих целе… 60 байт - приемлема цена … Хотя после того как мне указали что можно тоже самое сделать в 2 строчках… стало уже интереснее :slight_smile:

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

Ну скажем так - впоследствии , да … если я после добавления новой строчки каждый раз буду сортировать , то по сути да - добавление новой строчки в отсортированный массив, Вот только
на начальном этапе этого массива нет и его надо вводить , соответственно говорить о том что он отсортирован не совсем корректно , после первого прохода да…
на сейчас это 5 строчек которые я уже немогу удалить

Ну тут конечно Вы правы… можно сейчас вручную отсортировать мои данные заново записать их в еепром а потом при добавлении новой строчки как сказали впихивать ее между двумя другими в нужное место…
В самом начале я не подумал о таком методе… и решил сделать это с помощью сортировки… Сейчас мне открыли глаза и скорее всего я так и сделаю , если следующие задачи не заставят меня использовать под это рам… но не суть … Все дело в том , что я старой закалки , и меня всегда учили добиваться поставленной задачи или убеждаться что ее нельзя решить по каким либо причинам… соответственно раз я изначально поставил задачу отсортировать свой список , пусть я и не буду этим пользоваться так как действительно расточительно если можно решить другим способом…но разобраться почему не работает у меня сортировка, почему не работает у мееня malloc , почему не работает new char мне теперь покоя нет даст!.. :slightly_smiling_face: глупо - но так уж привык

Почему нет? Есть, просто нулевой. Просто функция добавления записи должна искать место для этой записи, а найдя - сдвинуть существующие, если нужно. Сортировка естественным путём.

вообще-то я знаю , что это такое … сам рос и учился во времена мк-61 , а поже двк радио рк и т.д конечно на некоторе время мне пришлось выпасть из этой сферы , возможно как и большинству , пожтому много пробелов - не вижу в этом ничего предрасудительного…
Конечно сейчас гораздо проще , но даже хороший программист иногда замыливается глаз и он не видит очевидных вещей, ну или как говориться все знать невозможно сталкивается с чем-то новым… так если есть форумы почему ж не воспользоваться сим благом…

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

Ну скажем не совсем нулевой :slight_smile: для отладки уже пришлось туда воткнуть несколько строк со связями , но по сути да Вы правы… основная задача такая… :slightly_smiling_face:

Очень познавательно. Особенно мне, как энтомологу-любителю. :wink:
Но оставим ёрничание.

Лежат себе некие слова-названия-строки в ЕЕпроме и пусть себе. У каждой строки есть индекс - точка ее начала в еепроме. Конец её, как завещано Керниганом и Ричи - определяется нулём.
Вот эти индексы - есть содержимое массива, который и следует сортировать. Если в традициях реляционных БД на строки что-то ссылается - то пусть ссылается на истинное местоположение, которое никто никуда двигать не должен, или можно хранить индексы уже в порядке и ссылаться косвенно, то есть сперва на индекс, а он уже укажет на местоположение строки. Двигать строки в памяти - ну как-то совсем бредово, на мой вкус, может кому-то нравится? - я не знаю.
Еще раз, для доходчивости - ЕЕпром - не магнитная лента, это устройство с произвольным доступом. То есть можно прочесть сперва 13-ю строку, а потом 6-ю. Нет никакого смысла их там реально перемещать. Память на индексы? - не смешите! - ТС пишет, что там у него 40 строк… ну да 80 байт потратим…

Если под строки отводится равное кол-во символов, то достаточно хранить 1 байт индекса, а смещение вычислять простой алгеброй. Не думаю, что у него больше 256 строк будет.
Upd. Ох придёцца видимо все-же расчехлять студию.

ждём’c с нетерпением…

Ох, Дет… Себя - не бережёшь. Низзя так!

??? С чего бы? …просто спросил, насинг прайвит…

Я не хочу Вас напрягать пока сам не попробую …
Я такой вариант попробую, но все же хотелось -бы разобраться что не так с сортировкой :roll_eyes: :face_holding_back_tears:

исправленый код , вроде я все учел , по крайнее мере в соответствии с учебником …

но все - же работает неправильно . если судить по дампам масив создается , память выделяется , указатели верные ссылаются на верное место , но … после qsort массив указателей сбивается , указатели улетают в конец массива соответственно я ничего не вижу…
С другой стороны если тот же массив иницировать изначально списком , а не брать из еепром , то сортировка работает нормально … остается предположить , что мое заполнение массива указателей значением еепром конфликтует с операторами сортировки

//                               #include <dumpmon.h>
#include <stdlib.h>
#include <string.h>
#include <EEPROM.h>

char fd[20];
char *MyStr[30];


void setup() {
  Serial.begin(19200);
  //                   dumpmonSetup(19200);
  WriteEEP();  //заполнить еепром для проверки
  MySort();    // попытка отсортировать
}

void loop() {
}


void MySort(void) {
  int z, zz;
  char *s;
  for (z = 0; z < 7; z++) {
    EEPROM.get(z * 20, fd);
    Serial.println(fd);
    s = (char *)calloc(20, 1);
    if (s == NULL) {
      Serial.println("Memory not");
    } else {
      Serial.println("Memory Yes");
      MyStr[z] = s;
      strcpy(MyStr[z], fd);
    }
  }
  Serial.println("------------end array eeprom----------------");

  for (z = 0; z < 7; z++) Serial.println(MyStr[z]);

  Serial.println("------------end array ram----------------");

  /// watch(MyStr, "Ms");
  // breakpoint("in watch");
  int qq = sizeof(MyStr) / sizeof(char *);
  qsort(MyStr, qq, sizeof(char *), MyCmp);
  // watch(MyStr, "Mstr");
  // breakpoint("out watch");
  for (z = 0; z < 7; z++) {
    Serial.println(MyStr[z]);
  }
  Serial.println("-------------sorted ----------------");



  for (z = 0; z < 7; z++) {
    free(MyStr[z]);
    MyStr[z] = NULL;
  }
}

int MyCmp(const void *p1, const void *p2) {
  const char *s1 = *(const char **)p1;
  const char *s2 = *(const char **)p2;
  return strcmp(s1, s2);
}

void WriteEEP(void) {

  char mem[20];
  const String ff = "                    ";
  String f0 = "A.CURRENT";
  String f5 = "Akai";
  String f2 = "Costa";
  String f3 = "India";
  String f4 = "Traton";
  String f1 = "Old";
  ff.toCharArray(mem, 20);  // очищенная строка
  EEPROM.put(0, mem);
  ff.toCharArray(mem, 20);  // очищенная строка
  f0.toCharArray(mem, 20);  //строка со значением определенной длины 20 символов
  mem[19] = 0;              // 20 символ - код строки от (0-150)
  EEPROM.put(20, mem);
  ff.toCharArray(mem, 20);
  f1.toCharArray(mem, 20);
  mem[19] = 5;
  EEPROM.put(40, mem);
  ff.toCharArray(mem, 20);
  f2.toCharArray(mem, 20);
  mem[19] = 2;
  EEPROM.put(60, mem);
  ff.toCharArray(mem, 20);
  f3.toCharArray(mem, 20);
  mem[19] = 4;
  EEPROM.put(80, mem);
  ff.toCharArray(mem, 20);
  f4.toCharArray(mem, 20);
  mem[19] = 3;
  EEPROM.put(100, mem);
  ff.toCharArray(mem, 20);
  f5.toCharArray(mem, 20);
  mem[19] = 1;
  EEPROM.put(140, mem);
  ff.toCharArray(mem, 20);
  f5.toCharArray(mem, 20);
  mem[19] = 1;
  EEPROM.put(140, mem);
}

0x034A адрес массива и список указателей

 s = (char *)calloc(20, 1);
    if (s == NULL) {
      Serial.println("Memory not");
    } else {
      Serial.println("Memory Yes");
      MyStr[z] = s;
      strcpy(MyStr[z], fd);
    }

конфликтует

int qq = sizeof(MyStr) / sizeof(char *);
  qsort(MyStr, qq, sizeof(char *), MyCmp);

Исходил из этого
EEPROM.get(z * 20, fd);
25я строка в новом коде

Да верно , строки одинакового размера , 19 байт + 1 байт на индекс для связи с другими таблицами… К сожалению пришлось его в вести т.к адрес строки в еепром не могу использовать из за того , что они могут смещаться на адресах… :smile: могли … если использовать сортировку в рам … если использовать по индексам необходимость в 20 байте скорее всего отпадет

Вопрос по сортировке с помощью qsort снят

но если есть замечания по 'правильности использования этих кусков , с удовольствием выслушаю

 char *s;

-----------------

 s = (char *)calloc(20, 1);
    if (s == NULL) {
      Serial.println("Memory not");
    } else {
      Serial.println("Memory Yes");
      MyStr[z] = s;
      strcpy(MyStr[z], fd);
    }
------------------------

  for (z = 0; z < 7; z++) {
    free(MyStr[z]);
    MyStr[z] = NULL;
  }



теперь буду пробовать и те что предложили выше…:slight_smile:

Роман, давайте Вы попробуете что-то делать, а не спорить со старшими. И вообще, пока хоть немного не научитесь, попридержали бы Вы своё мнение при себе. Вы несёт какой-то запредельный бред, но с таким умным видом.

Потому что средства настолько неадекватны стоящей задаче… Вы не пробовали стрелять уток при помощи С-300 или хотя бы “Иглы”?

Чего Вы там поняли? В данном случае они (new и malloc) ничем (от слова “совсем ничем”) не отличаются друг от друга - это просто одно и тоже! Открыть Вам большой секрет? Оператор new в Ардуино реализован вот так:

void *operator new(size_t size) {
      return malloc(size);
}

Как видите от malloc от отличается просто кардинально!

Вам это приснилось. Стек может проломить кучу, но чтобы куча проломила стек - никогда! Такого не бывает в принципе.

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

1 лайк