0

I'm trying to receive 9 float data using UART, every float is sent in the form XXX.XX. So I'm going to receive 5*9 =45 informations.

I tried to make the data received in a array of 45 char then I can do what I want with this array, but I get this famous error when i run my application : Segmentation fault (core dumped)

my code is

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include <string>
#include <string.h>
#include <errno.h>
#include <wiringSerial.h>
using namespace std;
int main (){
    int fd;
    float courant;
    float voltage;
    float activepower;
    float reactivepower;
    float apparentpower;
    float powerfactor;
    float frequency;
    float temperature;
    float indexIns;
    string courantC;
    string voltageC;
    string activepowerC;
    string reactivepowerC;
    string apparentpowerC;
    string powerfactorC;
    string frequencyC;
    string temperatureC;
    string indexinsC;

    char receivedData[45];
    int i=0;
    if ((fd = serialOpen("/dev/ttyS1",9600)) < 0)
    {
        fprintf(stderr,"Unable to open serial device %s\n",strerror(errno));
        return 1;
    }
    // Loop , getting and printing characters

    for (int j=0; j<45; j++)
    {
        i = serialGetchar(fd);
        receivedData[j] = char(i);

        if (j = 44) {
            j = 0;

            courantC = receivedData[0]+receivedData[1]+receivedData[2]+"." + receivedData[3]+receivedData[4];
            voltageC = receivedData[5]+receivedData[6]+receivedData[7]+"." + receivedData[8]+receivedData[9];
            activepowerC = receivedData[10]+receivedData[11]+receivedData[12]+"." + receivedData[13]+receivedData[14];
            reactivepowerC = receivedData[15]+receivedData[16]+receivedData[17]+"." + receivedData[18]+receivedData[19];
            apparentpowerC = receivedData[20]+receivedData[21]+receivedData[22]+"." + receivedData[23]+receivedData[24];
            powerfactorC = receivedData[25]+receivedData[26]+receivedData[27]+"." + receivedData[28]+receivedData[29];
            frequencyC = receivedData[30]+receivedData[31]+receivedData[32]+"." + receivedData[33]+receivedData[34];
            temperatureC = receivedData[35]+receivedData[36]+receivedData[37]+"." + receivedData[38]+receivedData[39];
            indexinsC = receivedData[40]+receivedData[41]+receivedData[42]+"." + receivedData[43]+receivedData[44];

           
        }
        printf("a=%c ", char(i));

        fflush(stdout);

The command used to compile

gcc receiveData.cpp -o receiveData -lwiringPi -lpthread -lstdc++
  • Please improve your formatting, it is very hard to read your code. – 12431234123412341234123 Sep 08 '20 at 11:31
  • 5
    Think about `if (j=44)` and what's really happening here. – Some programmer dude Sep 08 '20 at 11:33
  • Why do you try to add characters (or integers, characters are integers in C) with a const array (`"."`)? This makes no sense and probably causes UB. What are you trying to do? I think you should learn what are arrays, pointers and what adding integers to it does first. – 12431234123412341234123 Sep 08 '20 at 11:34
  • 2
    Furthermore, `receivedData[0]+receivedData[1]` etc. doesn't create a string, it just adds integer values. – Some programmer dude Sep 08 '20 at 11:34
  • your code is C with `std::string`. Read about [Why is “using namespace std;” considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) and your life will be easier if you realize that C and C++ are different languages (although you can write non-idiomatic c++ that is also valid C) – 463035818_is_not_an_ai Sep 08 '20 at 11:37
  • @idclev463035818 It is C++, i do not see how you think that code is C. It uses many things that are the same in C but should be done different in C++, but it is still C++. It is also tagged C++, so this part is correct. – 12431234123412341234123 Sep 08 '20 at 11:38
  • for starters you should use the c++ headers `` instead of the c headers `` – 463035818_is_not_an_ai Sep 08 '20 at 11:38
  • 2
    Have you tried using a debugger? – user253751 Sep 08 '20 at 11:39
  • @12431234123412341234123 if OP had used `std::string` consistently they would not face the problem, other than `std::string` its all C – 463035818_is_not_an_ai Sep 08 '20 at 11:39
  • @idclev463035818 It is bad C++, but it is still C++ and not C. `int main()` is also C++ and not allowed in C. – 12431234123412341234123 Sep 08 '20 at 11:44
  • @12431234123412341234123 it was a well intended tip to OP. I didnt claim that this is **the** problem with the code, maybe I didn't make that clear enough – 463035818_is_not_an_ai Sep 08 '20 at 11:47
  • Actually, why are you doing the `if (j == 44)` part inside the loop? Why not simply use the loop to read all bytes, then *after* the loop take the data you have read and separate it into the different values needed. That would simplify your code a little, and remove one serious bug (that right now leads to *undefined behavior*). – Some programmer dude Sep 08 '20 at 11:47
  • `c1 + "." + c2` is not string concatenation when `c1` and `c2` are not strings, but chars. – chi Sep 08 '20 at 11:54
  • Why do you link to wiringPi and pthread? You do not use this libraries. – 12431234123412341234123 Sep 08 '20 at 11:57

1 Answers1

0

This line:

courantC = receivedData[0]+receivedData[1]+receivedData[2]+"." + receivedData[3]+receivedData[4];

causes undefined behavior (UB) and is probably the cause of the segment fault. In this line you have an array of char, this here ".", with 2 chars, '.' and '\0'. This array is stored somewhere. When you use it like this it decays to a pointer that points at the start of the array. The rest are all char, which are integers in C. They are added together and added to the pointer pointing to the array ".". This pointer then points to some unknown memory region which is accessed by the String class to be copied to courantC. But accessing the region causes UB.