C++ C++;将字符数组传递给函数,对堆有效,但对堆栈无效?
我在Arduino uno上写下了这段代码,在这个过程中我学到了很多东西 这段代码可以工作,因为它从串行端口读入一个字符串,并返回一个serial.print语句C++ C++;将字符数组传递给函数,对堆有效,但对堆栈无效?,c++,arrays,arduino,stack,heap-memory,C++,Arrays,Arduino,Stack,Heap Memory,我在Arduino uno上写下了这段代码,在这个过程中我学到了很多东西 这段代码可以工作,因为它从串行端口读入一个字符串,并返回一个serial.print语句 #include <Arduino.h> #include <IRLibRecv.h> #include <stdio.h> #define BAUDRATE 9600 #define debug 1 #define develop 0 #define MSG_SRL_IN_SIZE 64 bo
#include <Arduino.h>
#include <IRLibRecv.h>
#include <stdio.h>
#define BAUDRATE 9600
#define debug 1
#define develop 0
#define MSG_SRL_IN_SIZE 64
bool checkForSerialMsgs(char *message);
void test();
int msgIndex = 0;
char message[MSG_SRL_IN_SIZE] = {0};
void setup() {
Serial.begin(BAUDRATE);
while (!Serial);
}
void loop() {
// char message[MSG_SRL_IN_SIZE] = {0};
if(checkForSerialMsgs(message)) {
Serial.println(message);
}
}
bool checkForSerialMsgs(char *message)
{
bool msgComplete = false;
while (Serial.available() > 0) {
char buf = Serial.read();
if (buf == '\n') {
msgComplete = true;
msgIndex = 0;
break;
}
else if(buf == '\r') {
continue;
}
else if(msgIndex < MSG_SRL_IN_SIZE && msgComplete == false) {
message[msgIndex++] = buf;
}
}
return msgComplete;
}
如果我注释掉那一行并在void loop()方法中取消注释第27行上的声明,那么我相信会在堆栈上声明缓冲区,因为它是一个局部变量
然而,那是行不通的
在这种情况下,由于缓冲区的大小是固定的,我认为在程序的生命周期中,它驻留在内存中不会有任何问题。但我将编写其他需要为Arduino创建相当大的动态数组的函数,我担心如果我这样做,很快就会得到一个碎片堆
然而,如果数组是在堆栈上创建的,我认为每次调用堆栈顶部的函数退出时,它们都会被清除干净
所以我的问题是,有没有办法在堆栈上而不是堆上创建数组
在回答之前,我经常被告知,使用更多的C++对象,比如字符串和向量,可以帮助我。但是,当我包含Arduino CPluPlus库来访问它们时,我的IDE会抛出一百条弃用错误消息,再也不会编译任何东西了。我要花上一个月的时间才能在这片土地上耕耘,所以我坚持这种更像C的方法
======================================================================
谢谢各位的回复
“描述一下那不起作用意味着什么。”
我的意思是当变量是全局变量时,我可以读取字符串
行-Serial.println(message);-在循环中(){}将其打印出来。
在loop()中创建消息数组时,消息在
是印刷的
“描述一下那不起作用意味着什么。你使用的是未初始化的
如果buf='\n'从未见过面,则在第二次和以后的调用中使用msgIndex。它是
最好在开始时重置变量。条件
msgComplete==false始终为true”
不,情况并非如此,当读入“\n”时,它被设置为true。然后,msgIndex也重置为0。有一个比赛条件。该函数在发送方完成传输之前读取字符
“堆中未分配全局字符消息”
谢谢你。我今天早上读的那篇文章似乎有
误导了我。考虑到我上次写C已经有多长时间了,这并不难
或者C++
bool checkForSerialMsgs(char*消息)总是可疑:要么应该是常量,要么缺少大小;函数无法猜测数组大小
当我在谷歌上搜索如何做到这一点时,我遇到了一些类似的评论,我不明白为什么这应该是常量。或者说,老实说,这会有什么不同。所以我怀疑这就是解决办法所在
虽然目前函数并不关心大小。我假设如果我发送了超过64个字符,它们将被忽略,因为条件-msgIndex#include <Arduino.h>
// #include <EEPROM.h>
#include <IRLibRecv.h>
#include <stdio.h>
#include <ArduinoJson.h>
#include <string>
using namespace std;
#define BAUDRATE 9600
#define debug 1
#define develop 0
#define MSG_SRL_IN_SIZE 64
bool checkForSerialMsgs();
int msgIndex = 0;
char message[MSG_SRL_IN_SIZE] = {0};
void setup() {
Serial.begin(BAUDRATE);
while (!Serial);
}
void loop() {
if(checkForSerialMsgs()) {
Serial.println(message);
}
}
bool checkForSerialMsgs()
{
bool msgComplete = false;
while (Serial.available() > 0) {
char buf = Serial.read();
if (buf == '\n') {
msgComplete = true;
msgIndex = 0;
break;
}
else if (buf == '\r') {
continue;
}
else if(msgIndex < MSG_SRL_IN_SIZE && msgComplete == false) {
message[msgIndex++] = buf;
}
}
return msgComplete;
}
#包括
//#包括
#包括
#包括
#包括
#包括
使用名称空间std;
#定义波特率9600
#定义调试1
#定义开发0
#定义大小为64的消息\u SRL\u
bool checkForSerialMsgs();
int-msgIndex=0;
字符消息[MSG_SRL_IN_SIZE]={0};
无效设置(){
串行开始(波特率);
而(!串行);
}
void循环(){
if(checkForSerialMsgs()){
Serial.println(消息);
}
}
bool checkForSerialMsgs()
{
bool msgComplete=false;
while(Serial.available()>0){
char buf=Serial.read();
如果(buf=='\n'){
msgComplete=true;
msgIndex=0;
打破
}
else if(buf=='\r'){
继续;
}
else if(msgIndex
很抱歉浪费了大家的时间,但至少我学到了一些东西
干杯所以这不起作用:
void loop() {
char message[MSG_SRL_IN_SIZE] = {0};
if(checkForSerialMsgs(message)) {
Serial.println(message);
}
}
为什么呢?因为每次调用循环()
时都会创建并清除消息。因此,它会一直忘记您写入的所有内容,并且您可能会打印最后几个字符(但由于波特率非常低,所以通常只有'\0',因为您的速度足够快,无法获得多个字符)
顺便说一句,它也在堆栈上。描述什么是,什么是不起作用的意思。如果buf=='\n'
从未见过面,则在第二次和以后的调用中使用未初始化的msgIndex。最好在开始时重置变量。条件msgComplete==false
始终为真。堆中未分配全局char消息
。checkForSerialMsgs
显然希望在调用之间保留消息的内容,下一次调用可以在上一次停止的地方继续。当您使用全局缓冲区调用它时,内容实际上是保留的。当你用局部变量调用它时,它们不是——你每次都会从一个填满零的缓冲区开始。事实上,正如@S.M.所指出的,全局变量不是在堆上创建的,所以你最初的担心是放错地方了。bool checkForSerialMsgs(char*message)
总是可疑的:要么应该是常量,要么是缺少大小;函数无法猜测数组大小。
void loop() {
char message[MSG_SRL_IN_SIZE] = {0};
if(checkForSerialMsgs(message)) {
Serial.println(message);
}
}