字符串损坏 - 堆栈溢出?
String gets corrupted - stack overflow?
我很绝望!我想让我的 ESP8266 从 TCP 客户端接收一个字符串,执行相应的功能并给出一个 TCP 响应。但不幸的是,响应字符串以某种奇怪的方式损坏了:
假设我输入一个 'unknown command',前 11 个字节通过串行接口正确打印(其余为转储),客户端接收到的前 11 个字节为转储,但其余是正确的(请参阅脚本中的注释以下)。但是当我输入 'dim' 命令时,结果是正确的(但是 return 字符串也比 "error: unknown command" 短)。
目前我完全不知道如何解决这个问题,尽管我已经尝试了很多。
#include <WiFiClient.h>
#include <ESP8266WiFi.h>
#include <Wire.h>
#include <string.h>
struct parsed_query{
String command;
String arguments;
};
struct parsed_query parser(void){
// this function receives and parses a query
struct parsed_query result;
result.command="entered command";
result.arguments="entered arguments"
return result
}
char* str2char(String as_string){
int i_0=0;
while(as_string[i_0]!='[=10=]'){i_0++;}
char as_char[i_0+1];
as_char[i_0]='[=10=]';
for(int i=0;i<i_0;i++){
as_char[i]=as_string[i];
}
return as_char;
}
String executor(String command,String arguments){
String response;
if(command=="dim"){
response="dimming";
}
else if(command=="on"){
response="switching ON";
}
else{
response="error: unknown command";
}
return response;
}
void setup(){
// initialize serial interface, wifi & tcp-server
Serial.begin(115200);
WiFi.begin("<SSID>","<PASSWORD>");
while (WiFi.status() != WL_CONNECTED){delay(500);}
TCPserver.begin();
}
void loop() {
if(!client.connected()){
client=TCPserver.available();
}else{
struct parsed_query query=parser();
// This prints "error: unkno??*/???*??"
Serial.println(str2char(executor(query.command,query.arguments)));
// here, the client receives "????**?*??*?wn command"
client.write(str2char(executor(query.command,query.arguments))));
}
}
我有两个想法可能导致此结果(即使我不知道在我的代码中修复它的位置):
案例一:
也许,我在某个时候将按引用调用和按值调用结合在一起(如果是,在哪里??)
案例二:
我的程序导致堆栈溢出(如果是,在哪里??)
非常感谢任何帮助,因为我不想再多待一晚了。
在 str2char
中,您将返回一个指向局部数组的指针,但与每个局部变量一样,它在函数返回后不再存在。因此从返回的指针读取会导致未定义的行为。
在启用警告的情况下编译(强烈推荐)应该输出如下内容:
warning: address of local variable 'as_char' returned
(一)正确的代码是
#include <WiFiClient.h>
#include <ESP8266WiFi.h>
#include <Wire.h>
#include <string.h>
#define TCP_RESPONSE_L 1024
struct parsed_query{
String command;
String arguments;
};
struct parsed_query parser(void){
// this function receives and parses a query
struct parsed_query result;
result.command="entered command";
result.arguments="entered arguments"
return result
}
int str2char(char *as_char, String as_string, int max_length){
int i_0=0;
while(as_string[i_0]!='[=10=]'){
if(i_0>=max_length){as_string="error: caught an overflow! increase TCP_BUFFER_L";break;}
i_0++;
}
as_char[i_0]='[=10=]';
for(int i=0;i<i_0;i++){
as_char[i]=as_string[i];
}
return 1;
}
String executor(String command,String arguments){
String response;
if(command=="dim"){
response="dimming";
}
else if(command=="on"){
response="switching ON";
}
else{
response="error: unknown command";
}
return response;
}
void setup(){
// initialize serial interface, wifi & tcp-server
Serial.begin(115200);
WiFi.begin("<SSID>","<PASSWORD>");
while (WiFi.status() != WL_CONNECTED){delay(500);}
TCPserver.begin();
}
void loop() {
if(!client.connected()){
client=TCPserver.available();
}else{
struct parsed_query query=parser();
char response[TCP_RESPONSE_L];
str2char(response,executor(query.command,query.arguments),TCP_RESPONSE_L);
//prints fine
Serial.println(str2char(executor(query.command,query.arguments)));
//correctly sending to client
client.write(str2char(executor(query.command,query.arguments))));
}
}
我很绝望!我想让我的 ESP8266 从 TCP 客户端接收一个字符串,执行相应的功能并给出一个 TCP 响应。但不幸的是,响应字符串以某种奇怪的方式损坏了: 假设我输入一个 'unknown command',前 11 个字节通过串行接口正确打印(其余为转储),客户端接收到的前 11 个字节为转储,但其余是正确的(请参阅脚本中的注释以下)。但是当我输入 'dim' 命令时,结果是正确的(但是 return 字符串也比 "error: unknown command" 短)。 目前我完全不知道如何解决这个问题,尽管我已经尝试了很多。
#include <WiFiClient.h>
#include <ESP8266WiFi.h>
#include <Wire.h>
#include <string.h>
struct parsed_query{
String command;
String arguments;
};
struct parsed_query parser(void){
// this function receives and parses a query
struct parsed_query result;
result.command="entered command";
result.arguments="entered arguments"
return result
}
char* str2char(String as_string){
int i_0=0;
while(as_string[i_0]!='[=10=]'){i_0++;}
char as_char[i_0+1];
as_char[i_0]='[=10=]';
for(int i=0;i<i_0;i++){
as_char[i]=as_string[i];
}
return as_char;
}
String executor(String command,String arguments){
String response;
if(command=="dim"){
response="dimming";
}
else if(command=="on"){
response="switching ON";
}
else{
response="error: unknown command";
}
return response;
}
void setup(){
// initialize serial interface, wifi & tcp-server
Serial.begin(115200);
WiFi.begin("<SSID>","<PASSWORD>");
while (WiFi.status() != WL_CONNECTED){delay(500);}
TCPserver.begin();
}
void loop() {
if(!client.connected()){
client=TCPserver.available();
}else{
struct parsed_query query=parser();
// This prints "error: unkno??*/???*??"
Serial.println(str2char(executor(query.command,query.arguments)));
// here, the client receives "????**?*??*?wn command"
client.write(str2char(executor(query.command,query.arguments))));
}
}
我有两个想法可能导致此结果(即使我不知道在我的代码中修复它的位置):
案例一: 也许,我在某个时候将按引用调用和按值调用结合在一起(如果是,在哪里??)
案例二: 我的程序导致堆栈溢出(如果是,在哪里??)
非常感谢任何帮助,因为我不想再多待一晚了。
在 str2char
中,您将返回一个指向局部数组的指针,但与每个局部变量一样,它在函数返回后不再存在。因此从返回的指针读取会导致未定义的行为。
在启用警告的情况下编译(强烈推荐)应该输出如下内容:
warning: address of local variable 'as_char' returned
(一)正确的代码是
#include <WiFiClient.h>
#include <ESP8266WiFi.h>
#include <Wire.h>
#include <string.h>
#define TCP_RESPONSE_L 1024
struct parsed_query{
String command;
String arguments;
};
struct parsed_query parser(void){
// this function receives and parses a query
struct parsed_query result;
result.command="entered command";
result.arguments="entered arguments"
return result
}
int str2char(char *as_char, String as_string, int max_length){
int i_0=0;
while(as_string[i_0]!='[=10=]'){
if(i_0>=max_length){as_string="error: caught an overflow! increase TCP_BUFFER_L";break;}
i_0++;
}
as_char[i_0]='[=10=]';
for(int i=0;i<i_0;i++){
as_char[i]=as_string[i];
}
return 1;
}
String executor(String command,String arguments){
String response;
if(command=="dim"){
response="dimming";
}
else if(command=="on"){
response="switching ON";
}
else{
response="error: unknown command";
}
return response;
}
void setup(){
// initialize serial interface, wifi & tcp-server
Serial.begin(115200);
WiFi.begin("<SSID>","<PASSWORD>");
while (WiFi.status() != WL_CONNECTED){delay(500);}
TCPserver.begin();
}
void loop() {
if(!client.connected()){
client=TCPserver.available();
}else{
struct parsed_query query=parser();
char response[TCP_RESPONSE_L];
str2char(response,executor(query.command,query.arguments),TCP_RESPONSE_L);
//prints fine
Serial.println(str2char(executor(query.command,query.arguments)));
//correctly sending to client
client.write(str2char(executor(query.command,query.arguments))));
}
}