C++ Arduino-What';存储字符串数组的正确方法是什么?
在尝试填充字符串对象的动态数组时,我得到了一个程序的不可预测的行为。我试图简化程序,但找不出原因 仅供参考:C++ Arduino-What';存储字符串数组的正确方法是什么?,c++,string,arduino,C++,String,Arduino,在尝试填充字符串对象的动态数组时,我得到了一个程序的不可预测的行为。我试图简化程序,但找不出原因 仅供参考:debug()和debugLn()将数据打印到Serial,debugMem()打印可用内存量 因此,最简单的版本按预期工作(场景-分配一个包含3个字符串的全局数组,定义3个局部变量并将其值分配给数组元素): 其产出: >>>>>>>>>>1787<<<<<<<<<<1
debug()
和debugLn()
将数据打印到Serial
,debugMem()
打印可用内存量
因此,最简单的版本按预期工作(场景-分配一个包含3个字符串的全局数组,定义3个局部变量并将其值分配给数组元素):
其产出:
>>>>>>>>>>1787<<<<<<<<<<1
>>>>>>>>>>1753<<<<<<<<<<2
>>>>>>>>>>1683<<<<<<<<<<3
src: abcdefghijk
src located at 2294
dest1: azcdefghijk
dest1 located at 2288
dest2: axcdefghijk
dest2 located at 2282
arr[0]: abcdefghijk
arr[0] located at 493
arr[1]: abcdefghijk
arr[1] located at 499
arr[2]: abcdefghijk
arr[2] located at 505
>>>>>>>>>>1683<<<<<<<<<<4
>>>>>>>>>>1647<<<<<<<<<<1
Phone index: 0
Substring: 0..10
>>>>>>>>>>1647<<<<<<<<<<2
>>>>>>>>>>1634<<<<<<<<<<3
Phone to add: 1234567890
Phone located at 2273
Array allocated bytes: 6
Array located at 623
>>>>>>>>>>1626<<<<<<<<<<4
>>>>>>>>>>1626<<<<<<<<<<5
Added phone: 1234567890
Added phone located at 623
>>>>>>>>>>1613<<<<<<<<<<6
Phone index: 1
Substring: 11..21
>>>>>>>>>>1626<<<<<<<<<<2
>>>>>>>>>>1613<<<<<<<<<<3
Phone to add: 2345678901
Phone located at 2273
Array allocated bytes: 12
Array located at 657
>>>>>>>>>>1607<<<<<<<<<<4
>>>>>>>>>>1607<<<<<<<<<<5
Added phone: 2345678901
Added phone located at 663
>>>>>>>>>>1607<<<<<<<<<<6
Phone index: 2
Substring: 22..-1
>>>>>>>>>>1620<<<<<<<<<<2
>>>>>>>>>>1607<<<<<<<<<<3
Phone to add: 3456789012
Phone located at 2273
Array allocated bytes: 18
Array located at 657
>>>>>>>>>>1601<<<<<<<<<<4
>>>>>>>>>>1601<<<<<<<<<<5
Added phone: 3456789012
Added phone located at 669
>>>>>>>>>>1601<<<<<<<<<<6
Total phones count:3
>>>>>>>>>>1614<<<<<<<<<<7
loop
Phone0
Phone located at 657
Phone: 1234567890
Phone1
Phone located at 663
Phone: ‚56789012
Phone2
Phone located at 669
Phone: 3456789012
PS2:第二个示例的简短版本(具有最小调试输出):
String*手机;
int-phonescont;
无效设置(){
Serial.begin(9600);
字符串reply=“123456789023456789013456789012”;
电话(答复);;
}
void循环(){
debugln(F(“循环”);
for(int i=0;i=0){
toIndex=reply.indexOf(F(“,”),fromIndex);
String entryPhone=reply.substring(从索引到索引);
String*tmpArray=realloc(phonesArray,(count+1)*sizeof(String));
如果(tmpArray==NULL){
打破
}
phonesArray=tmpArray;
phonesArray[计数]=入口电话;
计数++;
从索引=到索引+1;
}
返回计数;
}
我相信你可以这样做
String arr[3];
arr[0] = "one";
arr[1] = "two";
arr[2] = "three";
如果数组需要增加元素数量,请使用std::vector
#include <vector> // include this header
// ...
std::vector<String> arr; // declare the array
arr.push_back("one"); // add as many elements as you want
arr.push_back("two");
arr.push_back("three");
arr[0]; // you can access the elements just like if it was a regular array
总结自己的调查结果和其他人的评论-
malloc()
/realloc()
应避免在Arduino程序中使用(至少是内置于Arduino IDE中的程序),始终使用new
运算符分配动态数组(尽管您需要为realloc()
函数定义一个自定义的替代方案) 1)在C++程序中不要使用<代码> MalOC < /COD>。2) 了解std::vector
。3) 了解智能指针。4) 如果你坚持使用(可怕的)原始指针;至少要正确地执行,并在您自己之后清理—您的程序泄漏。@JesperJuhl我同意#1,但对于#2和#3,Arduino的资源非常有限,所以通常使用原始指针和数组。@Johnny Mopp在这种情况下,4肯定会起作用。。还有,std::unique_ptr
完全优化了—这是一个0开销的抽象。此外如果这就是OPs代码的全部错误,我们将是金黄色的。但事实并非如此。基本上是用C++编译器编译的坏C。什么是<代码>字符串< /代码>?您还没有向我们展示它的定义/代码。@JesperJuhl在Arduino上没有std
。是一个特定于Arduino的类。或者你可以使用std::string
而不是char
的原始数组来获得更快乐的生活。@user1754322我问的是MCU程序,没有内置的向量实现等等。对不起,我不知道。我更新了答案。这行得通吗?@user1754322似乎我有一个想法,但它似乎不适合我(主要是因为内存大小非常有限)。我希望使用realloc()来简化数组的扩展。此外,一个保留字符串*和(分隔)字符串实例数组的选项本身也可以工作,但需要更多内存,而且会导致其碎片化。如果这是唯一正确的方法-好的,但是我不明白为什么我的第一个代码示例可以工作。
String* arr;
void setup() {
Serial.begin(9600);
String src = "abcdefghijk";
arr = malloc(3 * sizeof(String));
String dest1 = src;
String dest2 = src;
arr[0] = src.substring(0);
arr[1] = dest1.substring(0);
arr[2] = dest2.substring(0);
dest1.setCharAt(1, 'z');
dest2.setCharAt(1, 'x');
}
String* phones;
int phonesCount;
void setup() {
Serial.begin(9600);
String reply = "1234567890,2345678901,3456789012";
fillPhones(reply);
}
void loop() {
debugln(F("loop"));
for(int i = 0; i < phonesCount; i++) {
debug(F("Phone"));
debugln(i);
debug(F("Phone located at "));
debugln((long)(phones + i));
debug(F("Phone: "));
debugln(*(phones + i));
}
}
void fillPhones(String reply) {
phonesCount = parsePhones(reply, phones);
}
int parsePhones(String reply, String* &phonesArray) {
phonesArray = NULL;
int count = 0;
int fromIndex = 0;
int toIndex = 0;
while(toIndex >= 0) {
toIndex = reply.indexOf(F(","), fromIndex);
String entryPhone = reply.substring(fromIndex, toIndex);
String* tmpArray = realloc(phonesArray, (count + 1) * sizeof(String));
if(tmpArray == NULL) {
break;
}
phonesArray = tmpArray;
phonesArray[count] = entryPhone;
count++;
fromIndex = toIndex + 1;
}
return count;
}
String arr[3];
arr[0] = "one";
arr[1] = "two";
arr[2] = "three";
#include <vector> // include this header
// ...
std::vector<String> arr; // declare the array
arr.push_back("one"); // add as many elements as you want
arr.push_back("two");
arr.push_back("three");
arr[0]; // you can access the elements just like if it was a regular array
const unsigned MAX_PHONES = 1024;
String* arr = new String*[MAX_PHONES];
unsinged arrSize = 0;
// ...
// add new string
if(arrSize < MAX_PHONES)
arr[arrSize++] = new String;
else
assert(false && "MAX_PHONES exceeded");
// releasing memory
for(int i=0; i<arrSize; i++) delete arr[i];
delete[] arr;