Проблема с использованием массива внутри оператора switch

У меня возникла проблема при использовании оператора switch для проверки чего-либо внутри массива. Я использую int в качестве переключателя, затем я сравниваю массивы символов, используя strstr. Итак, это читается так:

void function(char *buffer, uint32_t size){
  char *p=(char*)malloc(compareSize); //compareSize — размер сравниваемого текста
  #define TXTCOMPARE1 (char*)"Sample Text 1"
  #define TXTCOMPARE2 (char*)"Sample Text 2"
  #define TXTCOMPARE3 (char*)"Sample Text 3"
  switch(intCompare){
    case COMPARE1 :
      p = strstr(buffer,TXTCOMPARE1); break;
    case COMPARE2 :
      p = strstr(buffer,TXTCOMPARE2); break;
    case COMPARE3 :
      p = strstr(buffer,TXTCOMPARE3); break;
  }
  if(p!=NULL) { Serial.println("Success!"); }
  else { Serial.println("No match"); }
    memset(&p,0,sizeof(p);
}

Этот метод не работает, и p всегда равен NULL. Однако, когда я пишу его без switch(), он отлично сравнивается:

//с использованием того же объявления p, что и выше
p = strstr(buffer,TXTCOMPARE1);
if(p != NULL) { Serial.print("Success:"); }
else { Serial.print("No Match"); }

Почему оператор switch дает разные результаты для вызова одной и той же функции?

ОТРЕДАКТИРОВАНО: На самом деле кажется, что он везде ломается, когда я устанавливаю более одного вызова p = strstr(...). Когда есть только один strstr, он работает, когда используются два или более, он не работает...

, 👍2

Обсуждение

Вы определили COMPARE1, COMPARE2 и COMPARE3? Где ваш оператор присвоения значения для intCompare?, @Kugan Kumar

Да, я извиняюсь, что упустил это. Но это почти то же самое, что я делаю, за исключением того, что intCompare передается в function(char *buffer, uint32_t size, int intCompare). Но когда у меня есть несколько случаев, p __always__ NULL, @Andrew

Я не понимаю в этом коде три вещи: 1) Почему вы делаете malloc() в p, а затем перезаписываете p перед выполнением free()? Это не то, что нужно для работы strstr(). 2) Почему строки TXTCOMPARE имеют (char *) перед ними? Это не должно быть необходимо. 3) Почему вы делаете memset(&p,0,sizeof(p));? Это необычайно многословный способ сказать p = NULL;, и тогда p все равно выходит за рамки..., @John Burger

Спасибо @JohnBurger. 1) Я пытаюсь указать ожидаемый размер p из текста сравнения, который я ожидаю. 2) Компилятор выдавал мне предупреждения о преобразовании строк в char* при их определении, поэтому я приводил их как char*. Есть лучший способ сделать это? 3) Я думал, что пытаюсь очистить указатель p., @Andrew


2 ответа


0

Я решил эту проблему, было несколько проблем с кодом, который я нашел, так что спасибо за ваши комментарии. По сути, он заключается в операторах #define#. Во-первых, в Arduino не очень удобно использовать #define для строк/символов, только для int. Это связано с тем, что компилятор применяет текст каждый раз, когда он появляется в коде, поэтому он использует гораздо больше памяти. Проблема здесь решается с помощью static char TXTCOMPARE1 = {"Образец текста 1"};

Еще одна проблема заключалась в том, что в конце оператора #define не было завершающего символа NULL, поэтому программа продолжала искать конец стека при использовании strstr() и не найдя завершение, я думаю, мне просто повезло, что иногда это вообще срабатывало.

Более того, нет необходимости очищать p с помощью memset. Его необходимо объявить как NULL, а затем сбросить после переключения с помощью if(p){p = NULL;.

И теперь это работает!

,

Хорошо, что вы это нашли, и спасибо за предостережение относительно #define и строк. Обратите внимание, что вы должны были использовать static const char TXTCOMPARE1[] = "Sample Text 1";, а также if (p) { p =NULL; } теряет if. Просто выполните p = NULL; — это меньше и быстрее. Ох и совершенно ненужно. p в любом случае исчезнет, когда выйдет за пределы области видимости: нет необходимости обнулять его., @John Burger

Другая проблема заключалась в том, что в конце оператора #define не было символа, завершающегося NULL - это неправда. Из вашего фрагмента трудно сказать, но #define просто выполняет текстовую замену., @Nick Gammon

Нет необходимости выделять память для p, просто объявите его как char *p = NULL; strstr, а затем вернет указатель на существующие строки. Все, что делает строка malloc, — это утечка памяти., @Andrew


1

Одна большая проблема заключается в том, что вы забыли операторы break для этих случаев. Поэтому, если он сравнивает первый и находит его, вы все равно получите null, потому что впоследствии он будет искать третий.

,