C++Arduino,在带有char指针参数的方法中使用sprintf,破坏了程序
C++ Arduino, use of sprintf inside a method with a char pointer parameter, breaks program
我花了一天的大部分时间来解决这个问题,并将其缩小到以下简单的程序来复制它:Test.ino
// the setup function runs once when you press reset or power the board
void setup() {
Serial.begin(9600);
}
// the loop function runs over and over again until power down or reset
void loop() {
char _message[16] = { ' ' };
char *message = _message;
int pins[1] = { 1 };
//testOne(pins, 35, 5); // WORKS!!
testTwo(pins, 35, 5, message); // Desn't Work...
}
void testOne(int sensorPins[], int userDefault, int offset) {
char _int_char[2];
sprintf(_int_char, "%d", 36);
Serial.println(_int_char);
}
void testTwo(int sensorPins[], int userDefault, int offset, char *message) {
char _int_char[2];
sprintf(_int_char, "%d", 37);
Serial.println(_int_char);
}
以上代码所做的只是调用testOne和testTwo函数。
testOne函数为循环的每次迭代提供写入串行窗口的值36的预期结果。
testTwo函数将以下内容写入串行窗口:"VMDPV_1|1_VMVMDPV_1|1_VM"。。。。。
只有当我将char*消息参数添加到函数中时才会发生这种情况。显然,这是一个非常简单的演示,有硬编码的值等…在我的实际代码中,我使用了参数,还有很多…
实际上是对sprintf的调用导致了这些问题。在我的实际代码中,我将此作为构建消息的一部分。当我在实际代码中注释掉sprintf行时,它就起作用了。但我当然需要这一行来将其中一个参数的值输入到消息中。
有人能告诉我为什么sprintf在一个有char*消息参数的函数中不起作用吗?
我使用的是Arduino UNO,并使用Visual Micro 1511.23.1在Visual Studio中编写了代码,这是基于安装的1.6.5版本的Arduino IDE设置构建的。
我也可以在arduino IDE中复制这一点,只是我得到了与"VMDPV_1…"不同的字符……我得到了一个,3,一个顶部有一个倒置逗号和一个正方形的字母O。
我正在Win10 64位PC上开发所有这些。
感谢您抽出时间,
Scott
由于缓冲区溢出,您的程序会产生未定义的行为。
char _int_char[2];
sprintf(_int_char, "%d", 37); // <-- buffer overrun
由于生成的字符串可能占用2个以上的字符,因此多余的字符会溢出_int_char
数组并覆盖内存。损坏之前被覆盖的存储器中的内容可能与参数message
有关。
与其创建一个2个字符的数组,不如声明该数组足够大,不会产生缓冲区溢出。
char _int_char[20];
sprintf(_int_char, "%d", some_integer);
除非您有超过19位的整数,否则现在不应该溢出缓冲区。
一个万无一失的解决方案是使用C++流,即std::ostringstream。然后,无论要输出的数据长度如何,都不必担心缓冲区溢出:
#include <sstream>
#include <string>
//...
std::string _int_char;
std::ostringstream strm;
strm << some_integer;
_int_char << strm.str();
在C中,字符串以0结尾,这意味着在调用sprintf之后,_int_char包含{'3'、'6'、'\0'}。这是一个3个字符的数组,您只为2个保留内存
char _int_char[2];
sprintf(_int_char, "%d", 36);
- Mongodb c++驱动程序:如何查询元素的数组
- C++,系统无法执行指定的程序
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到
- 重载操作程序时出错>>用于类中的字符串 memebr
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 试图在visual studio上用C++创建一个桌面应用程序
- 模板元程序查找相似的连续类型名称
- FFmpeg:制作一个应用程序比直接使用ffmepg更好吗
- 如何通过cpp程序运行shell脚本
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- IPC使用多个管道和分支进程来运行Python程序
- 如何将c++程序的一些输出传递给shell,以便在shell中使用
- 使用C++程序合并排序没有得到正确的输出
- 基于boost的程序的静态链接——zlib问题
- 程序崩溃并显示"std::out_of_range"错误
- 在C应用程序中运行C++(带有STL)函数
- 使用mongocxx驱动程序时包含头文件问题
- C++Arduino,在带有char指针参数的方法中使用sprintf,破坏了程序