我需要使用GSM模块解码GPS信号并将其发送到远程服务器。我分别生成了纬度和经度值,并连接到一个char数组中。因此,我可以轻松地将char*传递给GSM模块串行write()方法。但是那些串联的字符串包含错误的值。我检查了解码后的值,它们具有实数,但这仅在将其连接到我的char数组中时发生。我在Arduino Uno上运行以下代码:

void loop()
{
  char data[128];
  data[0]='\0';
  initialize();

  strncat(data,getLat(),10);
  strncat(data," ",2);
  strncat(data,getLon(),10);

  Serial.write(data);
  Serial.println();

}

char* getLat(){
  char buffer[10];
  dtostrf(flat, 3, 6, buffer);
  Serial.write(buffer);
  Serial.print(" ");
  return buffer;
}


输出看起来像这样:调用getLat()方法时,前两列的值刚刚打印出来(转换中没有错误),而后两个值是连接的部分。

 6.929772 79.947296    Àb 79.947296
 6.929772 79.947296    6.929772 79.947296
 6.929772 79.947296    6.929772 79.947296
 6.929772 79.947296    6.929772 79.947296
 6.929772 79.947296    6.929772 79tdt
 6.929772 79.947296    6.929772 79.947296
 6.929772 79.947296    6.vtet bztbt
 6.929772 79.947296    6.929772 79.947296


有人可以告诉我这里有什么问题吗?先感谢您。

最佳答案

如果将代码更改为实用且简单的'helloworld.cpp'文件,并使用GNU C ++编译器进行编译,则会警告您当前如何返回指向getLat( )超出范围:

#include <stdio.h>
#include <string.h>

char* getLat();

int main(int argc, char **argv)
{
    char test[20] = {0};
    strncpy(test,getLat(),10);
    fprintf(stdout, "%s\n", test);
    return 1;
}

char* getLat(){
  char buffer[10] = {0};
  memset(buffer,0,sizeof(buffer));
  strcpy(buffer, "Testycole");
  // dtostrf(flat, 3, 6, buffer);
  // Serial.write(buffer);
  // Serial.print(" ");
  return buffer;
}




编译:

$ g++ file.cpp
file.cpp: In function ‘char* getLat()’:
file.cpp:16:8: warning: address of local variable ‘buffer’ returned [-Wreturn-local-addr]
   char buffer[10] = {0};




在运行时,我看到了垃圾:

$ a.out
 ��




快速解决方法(但不一定是最佳解决方案)是在堆上分配缓冲区变量,而不是在getLat()范围内。像这样更改GetLat()代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char* getLat();

int main(int argc, char **argv)
{
    char test[20] = {0};
    char *heapBuffer = getLat();
    strncpy(test,heapBuffer,10);
    fprintf(stdout, "%s\n", test);
    //delete[] heapBuffer; // C++ deallocation; prevents memory leak.
    free(heapBuffer);    // C deallocation; prevents memory leak.

    return 1;
}


char* getLat(){
  //char *buffer = new char[10]; // C++ allocation
  char *buffer = (char*)malloc(10); // C allocation - to be a C purist.

  memset(buffer,0,sizeof(buffer));
  strcpy(buffer, "Testycole");
  // dtostrf(flat, 3, 6, buffer);
  // Serial.write(buffer);
  // Serial.print(" ");
  return buffer;
}


...这会产生更好的结果:

$ a.out
Testycole


不要忘记,完成处理后必须取消分配存储char [10]缓冲区对象的堆内存,否则就会发生内存泄漏。 :-)

07-24 14:11