c++ Global pointer problem

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
Oltronix
Inlägg: 408
Blev medlem: 10 december 2011, 21:24:38
Ort: Nynäs

c++ Global pointer problem

Inlägg av Oltronix »

Jag har en pointer som är global som jag vill använda i en funktion, men det fungerar inte. Värdet av pekaren i funktionen är inte rätt. När testar med ett enkelt exemplet så fungerar det som jag vill. Se kod nedan.

Kod: Markera allt

class cl1
{
  int  a,b;
  int *ptr, *ptr1;
public:
  cl1();
  void foo();
  void bar();
};
function.h

Kod: Markera allt

#include "function.h"
#include <unistd.h>
#include <iostream> 
cl1::cl1()
{
using namespace std;
cout << "cl1:b #1=" << cl1::b << endl;
cout << "cl1:ptr1 #1=" << cl1::ptr1 << endl;
b=4;
ptr1=&b;
cout << "cl1:b #2=" << cl1::b << endl;
cout << "cl1:ptr1 #2=" << cl1::ptr1 << endl;
}
void cl1::foo()
{
using namespace std;
a=1;
cout << "foo:a="<< a << endl;;
cout << "foo:ptr #1=" << cl1::ptr << endl;
ptr=&a;
cout << "foo:ptr #2=" << cl1::ptr << endl;
}
using namespace std;
void cl1::bar()
{
cout << "bar:a="<< a << endl;
cout << "bar:ptr=" << ptr << endl;
cout << "bar:b=" << cl1::b << endl;
cout << "bar:ptr1=" << cl1::ptr1 << endl;
}
function.cpp

Kod: Markera allt

#include "function.h"
int main(int argc, char *argv[])
{
   cl1 myCl1;
   myCl1.foo();
   myCl1.bar();
}
main.cpp
  • cl1:b #1=0
    cl1:ptr1 #1=0x7ffce4472cf0
    cl1:b #2=4
    cl1:ptr1 #2=0x7ffce4472bf4
    foo:a=1
    foo:ptr #1=0x400a00
    foo:ptr #2=0x7ffce4472bf0
    bar:a=1
    bar:ptr=0x7ffce4472bf0
    bar:b=4
    bar:ptr1=0x7ffce4472bf4
Utskrift vid körning. Vilket är vad jag förväntat mig.

Men med det jag vill köra är ett annat lite mer komplext test som inte fungerar som jag vill. Det jag vill göra är att anropa en funktion, setTest(), som tar en global pekare, matrix12, och setTest() anropar i sin tur setMatrix(MyWindow::matrix12, MyWindow::img1p); Anledningen att jag inte anropar setMatrix direkt med parametar är att jag har en knapp, emit, som skickar Qt-signal till slot, setTest(). Om man har knappar i Qt kan man inte skicka parametrar om jag fattat rätt.

Jag har utgått från:https://www.linux-apps.com/p/1132152/
Som jag modiferat lite då jag vill få flytande text som är mitt slutmål. Nedan koden som jag har problem med.

Kod: Markera allt

#ifndef MYWINDOW_H
#define MYWINDOW_H 
#include <QtGui>
#include <qledmatrix.h>
#define Debug
class MyWindow : public QWidget
{
      Q_OBJECT
public:
    MyWindow();
    void setMatrix1();    
    QLedMatrix matrix14;
    void setMatrix(QLedMatrix *matrix, QImage *img);
    QLedMatrix *matrix12;
    QImage *img1p;   
public slots:
//    void WClear();
    void setTest();
private:
    QVBoxLayout *mainLayout;
};
#endif // MYWINDOW_H
mywindow.h

Kod: Markera allt

#include "mywindow.h"
#include <iostream>

MyWindow::MyWindow()
{
    setWindowTitle("Signals and Slots Example3");
    using namespace std; 

    QRadioButton *radioButton = new QRadioButton("Clear");
    QRadioButton *radioButton1 = new QRadioButton("emit", this);

    mainLayout = new QVBoxLayout;
 
    const int img1_col=60,img1_row=16;
    QLedMatrix *matrix12 = new QLedMatrix;
    matrix12->setColumnCount(img1_col);
    matrix12->setRowCount(img1_row);
    cout << "matrix12=";
    cout << matrix12 << endl;

    mainLayout->addWidget(matrix12);
    mainLayout->addWidget(radioButton);
    mainLayout->addWidget(radioButton1);
    setLayout(mainLayout);

    connect(radioButton, SIGNAL(clicked()), matrix12, SLOT(EClear()));
    connect(radioButton1, SIGNAL(clicked()), this, SLOT(setTest()));
    QImage img1(":/erik8.png");

    QImage *img1p;
    img1p=&img1;

cout << "matrix12="<< matrix12 << endl;
    setMatrix(matrix12, img1p);
cout << "After call, matrix12="<< matrix12 << endl;
cout << "matrix12="<< matrix12 << endl;
cout << "img1p=" << img1p << endl;
}

void MyWindow::setTest()
{
   using namespace std;
   cout << endl;
   cout << "setTest nr1" << endl;
   cout << "matrix12="<< MyWindow::matrix12 << endl;
   cout << "img1p=" << MyWindow::img1p << std::endl;
   cout << "matrix14="<< &MyWindow::matrix14 << std::endl;
   cout << "setTEST nr2" << std::endl;
   setMatrix(MyWindow::matrix12, MyWindow::img1p);
}

void MyWindow::setMatrix(QLedMatrix *matrix, QImage *img) {
#ifdef Debug
using namespace std;
cout << endl;
cout << "setMatrix nr1 pil->" << endl;
cout << "matrix="<< matrix << endl;
cout << "matrix12="<< matrix12 << endl;
cout << "setMatrix nr2 pil->" << endl;
cout << endl;
#endif
    for(int row=0; row < matrix->rowCount(); ++row)    
    {
        for(int col=0; col < matrix->columnCount(); ++col) {
            if(img->pixel(col+3, row) == QLedMatrix::White) {
                matrix->setColorAt(row, col, QLedMatrix::Yellow); }
            else {
                matrix->setColorAt(row, col, QLedMatrix::Blue); }
        }
    }
}
mywindow.cpp
  • $ ./qledmatrix_demo
    matrix12=0xcc85a0
    matrix12=0xcc85a0

    setMatrix nr1 pil->
    matrix=0xcc85a0
    matrix12=0
    setMatrix nr2 pil->

    After call, matrix12=0xcc85a0
    matrix12=0xcc85a0
    img1p=0x7fff2dafdba0
Utskrift efter start av program.
  • setTest nr1
    matrix12=0
    img1p=0x4040f0
    matrix14=1
    setTEST nr2

    setMatrix nr1 pil->
    matrix=0
    matrix12=0
    setMatrix nr2 pil->

    Segmentation fault (core dumped)
Utskrift efter tryck på emit-knappen.

Vaför blir det "fel"? Vad är det för skillnad i de olika exemplen?
Vad skall jag åtgärda så att det blir som jag vill?

bildexempel finns här:
http://elektronikforumet.com/forum/view ... 43&t=89504
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Re: c++ Global pointer problem

Inlägg av johano »

Det kan inte vara så att du i konstruktorn oavsiktligt råkar skapa en ny lokal variabel med namnet "matrix12" som då döljer din klassvariabel?

Kod: Markera allt

    ...
    QLedMatrix *matrix12 = new QLedMatrix;
    ^^^^^^^^

    matrix12->setColumnCount(img1_col);
    matrix12->setRowCount(img1_row);
    cout << "matrix12=";
    cout << matrix12 << endl;
    ...
Edit:
kolla även QImage *img1p;

/johan
Användarvisningsbild
Oltronix
Inlägg: 408
Blev medlem: 10 december 2011, 21:24:38
Ort: Nynäs

Re: c++ Global pointer problem

Inlägg av Oltronix »

Tack!! Du är en pärla!

Kod: Markera allt

    cout << "&matrix12="<< &matrix12 << endl;
    //QLedMatrix *matrix12 = new QLedMatrix;
    QLedMatrix *matrix122 = new QLedMatrix;
    matrix12=matrix122;
    cout << "matrix12="<< matrix12 << endl;
    cout << "&matrix12="<< &matrix12 << endl;
Gjorde susen. Inte så vackert kanske men det fungerade.

Att använda cout << &matrix12 << endl; visade om det var lika eller olika pekare. Inte kunde jag tänka att det skulle kunna vara olika pekare. OOP är en ny värld för mig, man måste hålla tungan rätt i mun.

Du kan inte ana hur många timmar jag slagits med detta och blivit frusterad flera ggr. Men jag har lärt mig lite C++ och Qt där kunskapen var noll tidigare.

Tack igen.

Fortfarande "segment fault" troligen pga QImage *img1p; men det får jag fixa i morgon nu måste jag rusa.
//Erik

edit
Jaha du hittade även QImage *img1p;
Nerre
Inlägg: 26652
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: c++ Global pointer problem

Inlägg av Nerre »

Men det där felet har väl egentligen inget att göra med OOP eller C++? Det handlar ju bara om att en lokal variabel kan ha samma namn som en global och då blir det svårt att referera till den globala? Det problemet finns ju även i vanlig C?

Eller har jag missförstått vad problemet var?

För att undvika det brukar man väl försöka använda nån form av prefix på globala variabler så man inte riskerar att döpa en lokal variabel till samma sak?
kodar-holger
EF Sponsor
Inlägg: 916
Blev medlem: 26 maj 2014, 12:54:35
Ort: Karlskoga

Re: c++ Global pointer problem

Inlägg av kodar-holger »

Det brukar finnas kompilatorflaggor man kan slå på för att få varningar när man döljer andra variabler med en lokal deklaration. Även andra saker kan vara bra att slå på varningar för.
Användarvisningsbild
Oltronix
Inlägg: 408
Blev medlem: 10 december 2011, 21:24:38
Ort: Nynäs

Re: c++ Global pointer problem

Inlägg av Oltronix »

Nerre: Så kan man se det att jag blandade ihop lokala och globala identiferare. Iof kan jag debatera om detta har med OOP att göra det eller ej. Utan att säga att du har fel så var jag förvirrad och var helt övertygad att jag använde endast en och samma pekare i construktorn som i class-definitionen. Jag inser att jag var ute och cyklade i full fart.
För att undvika det brukar man väl försöka använda nån form av prefix på globala variabler så man inte riskerar att döpa en lokal variabel till samma sak?
Bra förslag!

Nu är jag glad att jag kan sudda min matris och återskapa den. Snart dags att flytta på texten.

Intressant är pekaren "img1p" verkar bete sig som diskfilepekare som stegar fram vid varje läsning. Jag får köra

Kod: Markera allt

QImage img1(":/erik8.png");
img1p=&img1;
varje gång jag skall avända img1p-pekaren igen. Den emanerar från *.qrc fil

Kod: Markera allt

<!DOCTYPE RCC><RCC version="1.0">
    <qresource prefix="/" >
        <file>erik8.png</file>
    </qresource>
</RCC> 
Användarvisningsbild
Oltronix
Inlägg: 408
Blev medlem: 10 december 2011, 21:24:38
Ort: Nynäs

Re: c++ Global pointer problem

Inlägg av Oltronix »

kodar-holger skrev:Det brukar finnas kompilatorflaggor man kan slå på för att få varningar när man döljer andra variabler med en lokal deklaration. Även andra saker kan vara bra att slå på varningar för.
Intessant! Jag får botanisera...
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Re: c++ Global pointer problem

Inlägg av johano »

Du ska nog inte tilldela pekarna värden från objekt allokerade på stacken sådär.
Ett objekt som initieras på stacken "lever" bara i det scope det finns i. I ditt fall så är inte den lokala variabeln img1 "giltig" utanför funktionen (konstruktorn),
och om du då tar adressen av den och tilldelar en pekare som gäller utanför detta scope så kommer det leda till problem.

Allokera istället img1p såhär:

Kod: Markera allt

img1p = new QImage(":/erik8.png");
så är den tillgänglig ända tills du delete:ar den.

/johan
Användarvisningsbild
Oltronix
Inlägg: 408
Blev medlem: 10 december 2011, 21:24:38
Ort: Nynäs

Re: c++ Global pointer problem

Inlägg av Oltronix »

Hm Det händer skumma, saker ibland, felmeddelanen intermitent, utan core dump. Kan bero på att jag använder stacken på fel sätt?
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Re: c++ Global pointer problem

Inlägg av johano »

Vad är det för felmeddelanden?

/j
Användarvisningsbild
Oltronix
Inlägg: 408
Blev medlem: 10 december 2011, 21:24:38
Ort: Nynäs

Re: c++ Global pointer problem

Inlägg av Oltronix »

När jag körde med

Kod: Markera allt

    QImage img1(":/erik8.png");
    img1p=&img1;
Får jag ibland följande felmeddelande
  • QImage::pixel: coordinate (10,0) out of range
    QImage::pixel: coordinate (11,0) out of range
    QImage::pixel: coordinate (12,0) out of range
    QImage::pixel: coordinate (13,0) out of range
    .
    .
    QImage::pixel: coordinate (55,15) out of range
    QImage::pixel: coordinate (56,15) out of range
    QImage::pixel: coordinate (57,15) out of range
    QImage::pixel: coordinate (58,15) out of range
    QImage::pixel: coordinate (59,15) out of range
Jag är osäker på om utskrifterna alltid startar på (10,0). Matrisen är 60x16 stor. Pekaren,img1p, pekar även lite här och där som jag nämt tidigare.

Kod: Markera allt

img1p = new QImage(":/erik8.png");
fungerar bra.Inga felmeddelanden och beter sig som jag förväntar mig. Tack!

Ni som kör Qt använder ni Qt Creater och Designer?

Hur vet man om saker ligger på stacken eller i programminnet, eller var data ,varibler, nu läggs ut av kompilatorn?
Letade i en C++-bok. Där fanns det inte ett pip om progammets stack. Söker man på nätet hittar jag bara bara hur man implementer en stack.
Mr Andersson
Inlägg: 1394
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: c++ Global pointer problem

Inlägg av Mr Andersson »

Lokala variabler ligger alltid* på stacken. Globala variabler och saker allokerade med new/malloc/etc. ligger på heapen.
Man måste även ta hänsyn till scope. Ta tex.

Kod: Markera allt

int global_i; // heap
void func()
{ // <-- nytt scope
  int i1 = 1; // stack
  if(i1)
  { // <-- nytt scope
    int i2 = i1 + 2; // stack
  } //<-- här slutar i2 att existera
} // <-- här slutar i1 att existera
*) Det finns undantag, men det stämmer för alla vanligt använda processorer.

Edit: det här kanske förklarar det lite bättre https://www.gribblelab.org/CBootCamp/7_ ... _Heap.html
kodar-holger
EF Sponsor
Inlägg: 916
Blev medlem: 26 maj 2014, 12:54:35
Ort: Karlskoga

Re: c++ Global pointer problem

Inlägg av kodar-holger »

Oltronix skrev: Ni som kör Qt använder ni Qt Creater och Designer?
Designer ja absolut. 100ggr enklare än att försöka få till det med kod. Minst.
Creator nej. Visual Studio med Qt addin.
Användarvisningsbild
Oltronix
Inlägg: 408
Blev medlem: 10 december 2011, 21:24:38
Ort: Nynäs

Re: c++ Global pointer problem

Inlägg av Oltronix »

Vad är det för skillnad, på de olika anropen

Kod: Markera allt

QImage img1(":/erik8.png");
och
img1p = new QImage(":/erik8.png");
förutom att img1p är en pekare i det senare fallet?

Varför blir inte img1p local variabel pss som matrix12 med anropet

Kod: Markera allt

QLedMatrix *matrix12 = new QLedMatrix;
Vilka kompilator/länkar-flaggor skall jag sätta på för att få varningar på detta? Det måste vara nått i *.pro eftersom jag använder qmake och make. Makefilen verkar inte var nått som man går in och hackar i om man skall bevara sitt förstånd. Jag kan önska mig två varningar. 1. När jag tilldelar matrix12 ett värde och det blir en lokal variabel och överider den globala varibeln matrix12. 2. När jag anropar setMatrix i setTest och de globala variblerna matrix12 och img1p är oiniterade.

Mr Andersson: Nu har jag läst på om stack och heap. Tack för input! Intresant, kanske självklart, att main() är en funktion och dess varibler ligger på stacken.

Vad använder unix/linux användare istället för Visual Studio?
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Re: c++ Global pointer problem

Inlägg av johano »

>> Vad är det för skillnad, på de olika anropen

Kod: Markera allt

QImage img1(":/erik8.png");
skapar ett QImage-objekt på _stacken_, och det objektet kommer raderas när du går ut ur "scope", d.v.s. när stacken rullas tillbaka, i dethär
fallet när konstruktorn returnerar.

Kod: Markera allt

img1p = new QImage(":/erik8.png");
däremot skapar ett QImage-objekt på _heapen_ och där kommer det finnas kvar tills du explicivt tar bort det med

Kod: Markera allt

delete img1p;
>> Varför blir inte img1p local variabel pss som matrix12 med anropet

Därför att img1p _deklareras_ som medlemsvariabel i klassen (men _tilldelas_ sitt värde i konstruktorn),

Kod: Markera allt

class MyWindow : public QWidget
{
public:
...
    QImage *img1p;   
}
matrix12 däremot både _deklareras_ och _tilldelas_ sitt värde (samtidigt) i konstruktorn.

Kod: Markera allt

MyWindow::MyWindow()
{
...
    QLedMatrix *matrix12 = new QLedMatrix;
}
/johan
Skriv svar