Reputation: 3192
I need to decode and send a GPS signal to a remote server using a GSM module. I generated Latitude and Longitude values separately and concatenated into a char
array. So I can easily pass a char*
to the GSM modules serial write()
method. But those concatenated string contains erroneous values. I checked for the decoded values and they have real numbers but this only happens as I concatenate it into my char
array. I run this code on an 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;
}
Output looks like this: first two columns has the values just printed when getLat()
methods are called (There are no errors in the conversion) and last two values are the concatenated part.
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
Can someone tell me what is wrong here? Thank you in advance.
Upvotes: 0
Views: 727
Reputation: 416
If you change your code to a practical and simple 'helloworld.cpp' file and compile it with a GNU C++ compiler, you are warned about the problem with how you are currently returning a pointer to something on the heap that gets destroyed when getLat() goes out of scope:
#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;
}
Compiling:
$ 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};
At runtime, I see garbage:
$ a.out
��
A quick fix, but not necessarily the best fix, is to allocate the buffer variable on the heap instead of within the scope of getLat(). Change GetLat() code like this:
#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;
}
...this yields better results:
$ a.out
Testycole
Don't forget that you have to deallocate the heap memory storing the char[10] buffer object after you finish with it, or you have yourself a memory leak. :-)
Upvotes: 2