Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

[Solved] Memory (de)allocation within slots and public functions



  • Hi!

    I have a form which has some buttons on it. Let's say I press ButtonA which clicked() signal is connected to its on_buttonA_clicked() slot. In this slot some memory is allocated with calloc() then deallocated with free(). Program works fine. But if I call a public member function from here (and I'd like to) called function1() and I put free() into this function, the program becomes unstable, crashes at exit. Clearly the cause of this behaviour is that free() cannot recognize the public variable I'm using. Is there a way to make this bug-free?

    Here is a sample class:
    @
    #ifndef WIDGET_H
    #define WIDGET_H

    #include <QWidget>

    namespace Ui {
    class Widget;
    }

    class Widget : public QWidget
    {
    Q_OBJECT

    public:
    explicit Widget(QWidget *parent = 0);
    void function1();
    char *pchar; //to allocate a char array on the heap
    ~Widget();

    private slots:
    void on_buttonA_clicked();

    private:
    Ui::Widget *ui;
    };

    #endif // WIDGET_H
    @


  • Moderators

    I won't go into commentary on your design, except to say that I feel strongly that it's mostly likely a series of poor choices (using calloc rather than new, using character arrays instead of Qt's native container classes, etc.) and should probably be written to be more C++-like rather than C-like.

    However, with that briefly said:

    Make sure you always initialize your pointers to 0 initially.

    If you call free on a pointer, be sure and set it's value to 0. If you try to free memory twice, you'll have a bad time. Calling free() on a null pointer is harmless.



  • It seems the problem occurs with a more complex data structure:

    @
    struct rek {
    QByteArray ID, Offset;
    unsigned int length;
    bool trans;
    char * string;
    };
    rek * record;

    void Widget::function1() {
    QMessageBox::information(this, tr("Ok."), record[0].string);
    }

    void Widget::on_buttonA_clicked() {
    rek * record=new rek[20]; //let's assume allocation was successful
    record[0].string=(char *)calloc(1000,sizeof(char)); //detto
    strcpy(record[0].string,"some text...");
    QMessageBox::information(this, tr("Ok."), record[0].string); //"some text..." appear in a messagebox
    function1(); //empty string or garbage appear in a messagebox - data structure unavailable, trying to free() it causes crash
    }
    @

    I'm not sure what would be more C++ like code, so if you could tell me I would be thankful. On the other hand I have to handle non-latin characters which are not stored in Unicode format so it seemed appropriate to stick to the old character arrays and string functions to prevent data loss.


  • Moderators

    You're redeclaring @rek *record@ in line 14, which is masking the declaration at line 7.



  • Thank you very much. Now I can use the debugger again. It couldn't handle this line, but it didn't tell me what the problem was either.


Log in to reply