Implementarea ArrayList eșuează pentru obiectul string (Arduino, Programare, Arduino Mega, C++)

geotehnie a intrebat.
a intrebat.

Folosesc o implementare personalizată în C++ a ArrayList bazată pe metoda găsită în Processing. Codul original este de Obed Isai Rios, , dar eu am adăugat un versiune pe Github cu o structură de fișiere mai explicită. Arraylistul este anexat de către add_string_item care funcționează bine în formatul arraylist->add_string_item("text string") dar eșuează atunci când aceeași intrare este o variabilă String. Următorul script ilustrează acest lucru:

#include "ArrayList.h"
void setup(){
  ArrayList *list = new ArrayList("text1");
  list->add_string_item("text2");
  String str = "text3";
  list->add_string_item(str);
}
void loop(){}

Acesta eșuează pe ultima linie cu mesaj de eroare:

no matching function for call to 'ArrayList::add_string_item(String&)'

sketch_aug24b.ino: In function 'void setup()':
sketch_aug24b:7: error: no matching function for call to 'ArrayList::add_string_item(String&)'
/Users/robinedwards/Documents/Arduino/libraries/ArrayList/ArrayList.h:17: note: candidates are: void ArrayList::add_string_item(char*)

Nu sunt familiarizat cu C++, așa că nu-mi pot da seama de ce această metodă acceptă un șir de caractere, dar nu și atunci când este atribuită unui obiect String. str. Sunt destul de sigur că este din cauză că trebuie să coercitez la char* dar nu sunt sigur cum să fac acest lucru. Am încercat toCharArray fără succes, deși aceasta pare a fi direcția corectă. Foarte recunoscător pentru orice asistență.

Codul ArrayList.cpp:

#include "Arduino.h"
#include "ArrayList.h"

ArrayList::ArrayList(char* init){
  stringlist = (char**)malloc(10*sizeof(char*));
  stringlist[0] = init;
  this->size = 1; 
}

ArrayList::~ArrayList(void)
{
}

void ArrayList::add_string_item(char* item){
  char **neulist = (char**)malloc((size+1)*sizeof(char*));
  for(int i=0; i<size; i++){
    neulist[i] = stringlist[i];
   }
   //
   neulist[size] = item;
   stringlist = neulist;
   size = size + 1;
}

void ArrayList::set_string_item(char* item, int index){
  stringlist[index] = item;
}

void ArrayList::remove_selected_item(int index){
  char **neulist = (char**)malloc((size-1)*sizeof(char*));
  //From Begining
  for(int i=0; i<index; i++){
    neulist[i] = stringlist[i]; 
  }
  //From next Index  
  for(int i=index; i<=size-1; i++){
    neulist[i] = stringlist[i+1];
  }
  //free(matrix);
  stringlist = neulist;
  size = size - 1;
}

void ArrayList::empty_list(){
   size = 1;
   char **neulist = (char**)malloc((size)*sizeof(char*));   
   stringlist = neulist;
   stringlist[0] = "EMPTY";
}

void ArrayList::display_string_list(){
   Serial.begin(9600);
  for(int i=0; i<size; i++){
    Serial.println(stringlist[i]);
   }
}

char** ArrayList::get_stringlist(){
  return this->stringlist;
}

char* ArrayList::get_item(int index){
  return this->stringlist[index];
}

void ArrayList::set_stringlist(char** stringlist){
  this->stringlist = stringlist;
}

int ArrayList::get_size(){
  return this->size;
}

1 răspunsuri
Peter Bloomfield

În teorie, , nu există niciun motiv pentru care nu ați putea să o apelați folosind toCharArray(). Ar trebui să o apelați astfel:

String str = "text3";
char * buf = new char[str.length()+1];
str.toCharArray(buf, str.length()+1);

list->add_string_item(buf);

Aceasta alocă un fișier char buffer, copiază datele șirului de caractere în el, apoi trece pointerul bufferului la lista care urmează să fie stocată. Rețineți că bufferul este cu un caracter mai mare decât șirul de caractere, deoarece trebuie să adauge un terminator nul la sfârșit.

Cu toate acestea, există un majoră problemă majoră cu restul codului dumneavoastră, care ar putea duce în cele din urmă la blocarea Arduino sau la alte acțiuni ciudate (în funcție de cât de mult utilizați obiectul listă).

Spre deosebire de Java, C++ nu este un limbaj de colectare a gunoiului, ceea ce înseamnă că nu va curăța automat memoria pentru dvs. Dacă apelați new sau malloc() pentru a aloca memorie heap, trebuie să apelați delete sau free() (respectiv) după ce ați terminat de folosit-o pentru a o dezaloca.

Simpla suprascriere a unui pointer cu un alt apel la malloc() nu este suficient; acest lucru are ca rezultat un scurgere de memorie. Aceasta înseamnă că blocul de memorie pe care îl folosea anterior este pierdut și nu mai poate fi reutilizat din nou atâta timp cât programul este în execuție. Pe o platformă precum Arduino, care are o memorie limitată, se poate ajunge foarte repede la epuizare.

Corectarea designului clasei dvs. este probabil dincolo de scopul unui răspuns pe acest site. V-aș recomanda cu tărie să lucrați prin intermediul unor tutoriale C++ (dintre care există sute online).

Ca o notă secundară, în general ar trebui să utilizați new/delete în loc de malloc()/free(). Nu este o diferență prea mare atunci când folosiți array-uri de char sau char*, , dar este important dacă doriți să alocați instanțe de clasă.

Comentarii

  • De mare ajutor 🙂 The toCharArray funcționează, dar ai dreptate, dar după un timp se blochează arduino. Cred că voi reveni la metodele array până când voi găsi timp să refac biblioteca… –  > Por geotheory.