0

I wrote a C++ program in Qt that used dynamic memory allocation, and I made sure to include the free() call at the end. However, when the program reaches the free statement, it crashes. (I know this because the test that I added never printed after the free statements) Anyway, here's the code:

#include <QCoreApplication>
#include <QSerialPort>
#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <Windows.h>
using namespace std;

int main(int argc, char *argv[])
{

QSerialPort serial0;
//serial.open(serial);

serial0.setBaudRate(QSerialPort::Baud9600);
serial0.setDataBits(QSerialPort::Data8);
serial0.setParity(QSerialPort::NoParity);
serial0.setStopBits(QSerialPort::OneStop);
serial0.setFlowControl(QSerialPort::NoFlowControl);

char *com="com";
int number;
char *comPlusNumber;

comPlusNumber=(char*) malloc(8*sizeof(char));

int j=10000;
while(j>0)
{
    number=j;
    sprintf(comPlusNumber, "%s%d",com,number);
    //printf("%s \n",comPlusNumber);

    serial0.setPortName(comPlusNumber);
    serial0.open(QIODevice::ReadWrite);

    if(serial0.isOpen()==true)
    {
        printf("YES*****************");
        printf("%s \n",comPlusNumber);
    }
    else
        //printf("No %d\n", number);

    serial0.close();
    j--;
}


free(com);
free(comPlusNumber);

printf("\n\n Test");
//QCoreApplication a(argc, argv);

//return a.exec();
}

I just wanted to make sure that I wasn't creating a memory leak.

Z Rev
  • 84
  • 1
  • 13

2 Answers2

1

Use the framework. You've got the power of Qt!

There are several problems:

  1. The C-style string manipulations are unnecessary and wrong. Use QString:

    auto name = QStringLiteral("COM%1").arg(i);
    
  2. You can't use the serial port without a QCoreApplication instance present.

  3. You shouldn't be testing for the presence of a port by iterating what you think might be valid ports. This is non-portable and unnecessary. Get a list of ports to start with.

Thus:

// https://github.com/KubaO/stackoverflown/tree/master/questions/simple-serial-35181906
#include <QtCore>
#include <QtSerialPort>

int main(int argc, char ** argv) {
   QCoreApplication app{argc, argv};
   QSerialPort serial;
   serial.setBaudRate(QSerialPort::Baud9600);
   serial.setDataBits(QSerialPort::Data8);
   serial.setParity(QSerialPort::NoParity);
   serial.setStopBits(QSerialPort::OneStop);
   serial.setFlowControl(QSerialPort::NoFlowControl);

   for (auto port : QSerialPortInfo::availablePorts()) {
      serial.setPort(port);
      serial.open(QIODevice::ReadWrite);
      if (serial.isOpen()) {
         qDebug() << "port" << port.portName() << "is open";
         serial.close();
      } else
         qDebug() << "port" << port.portName() << "couldn't be opened";
   }
}

Here's the output on my machine:

port "cu.serial1" is open
port "cu.usbserial-FTELA9I5" is open
port "cu.usbserial-PX9A3C3B" is open
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • Is there any way to check if the ports are open without the debug? I need to send the application (exe) to another machine that doesn't have Qt on it. – Z Rev Feb 03 '16 at 19:03
  • @ZRev This is just a demonstration. You can use whatever other code you desire. If you want to do console output using Qt, you can do so via `QTextStream` layered on top of `stdout` and `stdin`. See e.g. [this answer](http://stackoverflow.com/a/22310976/1329652). – Kuba hasn't forgotten Monica Feb 03 '16 at 20:09
  • @ZRev Of course Qt applications don't need Qt installed on the target. It's up to you to package your application correctly. If you want it to be a single .exe file, with no dependencies on non-system dlls, you'll need to use *both* static C++ runtime *and* static Qt. You'll have to build Qt yourself, see [e.g. here](http://stackoverflow.com/a/32613840/1329652) for a summary of related options to Qt's `configure`. – Kuba hasn't forgotten Monica Feb 03 '16 at 20:11
  • What are your machine specs? I ran this on four different machines, and only one, a Windows 7 desktop with an Intel i7, was able to detect a port other than com1 – Z Rev Feb 04 '16 at 14:36
  • @ZRev That's correct. Most contemporary systems won't have any serial ports on them! Why do you expect serial ports when there are none? – Kuba hasn't forgotten Monica Feb 05 '16 at 13:40
0

You can only free what you dynamically allocated. You never dynamically allocated anything for com, so passing it to free is an error. It's equivalent to free("com"); which attempts to free a string constant.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • Ah, I see. I originally tried to dynamically allocate com, so i must have forgotten to change it. Thanks for the spot! – Z Rev Feb 03 '16 at 17:21