• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

error: cast from ‘int*’ to ‘int’ loses precision [-fpermissive]

Object Storage Arubacloud
0 głosów
3,282 wizyt
pytanie zadane 10 maja 2017 w C i C++ przez Kugaz Nowicjusz (120 p.)

Dzień dobry,

Przepraszam że przychodzę z problemami ale od czegoś trzeba zacząć. Mianowicie, korzystam z software-u Intelji CLion do programowania w C++. Podczas przerabiania książki Symfonia C++ kompilator wyrzuca mi błąd taki jak w temacie. Akurat pracuje na Lubuntu 64x postawionym na wirtualnej maszynie.

Przejdźmy do kodu:

#include <iostream>
using namespace std;
#include <new>
                                //1

/*************************************************************/
int main()
{   // wstepna rezerwacja duzego obszaru pamieci, czyli kupujemy grunt na osiedle domow
    int *osiedle = new int[5000];                   //2
    //niwelowanie zdobytego obszaru
    for(int i = 0; i < 5000; i++) osiedle[i] = 1;   //3

    //teraz na tym terenie mozemy tworzyc obiekty, umieszczenie obiektu
    void *gdzie = &osiedle[102];                    //4
    int *wskint = new (gdzie) int;                  //5
    // -- praca nad tym obiektem --
    *wskint = 222;                                  //6
    cout << "*wskint = " << (*wskint) << endl;

    //==============================================================
    gdzie = &osiedle[102];
    int * wTabi = new (gdzie) int[3];                //7

    // praca z ta tablica
    for(int m = 0; m < 3; m++)
    {
        wTabi[m] = 1000 + m;
        cout << "wTabi[" << m << "] = " << wTabi[m] << " ";
    }
    cout << endl;
    //==============================================================
    gdzie = &osiedle[106];
    double * wTabd = new (gdzie) double[3];          //8

    // praca z ta tablica
    for(int n = 0; n < 3; n++)
    {
        wTabd[n] = 1 + ( 0.1 * n);
        cout << "wTabd[" << n << "] = " << wTabd[n] << " ";
    }
    cout << endl;
    //w miejscu o adresie podanym liczbowo===========================
    cout << "napisz jakis adres pomiedzy: "
         << reinterpret_cast<int >(&osiedle[112])
         << " - "
         << reinterpret_cast<int >(&osiedle[116])
         << "\na ja tam zbuduje ci obiekt: ";

    int adres;
    cin >> adres;
    gdzie = reinterpret_cast<void *>(adres);        //10
    int * wskA = new (gdzie) int;                   //11

    //---praca z tym obiektem----
    *wskA = 114;
    cout << "Wartosc = " << (*wskA) << endl;

    //===============================================================
    cout << "zobaczymy na te dzialke \n";           //12
    for(int k =99; k < 116; k++)
        cout << "[" << k << "]=" << osiedle[k] << endl;

    delete [] osiedle;
    //system("pause");
    //return 0;

}

Dokładny wynik kompilacji:

/home/kugaz/Downloads/clion-2017.1.1/bin/cmake/bin/cmake --build /home/kugaz/CLionProjects/untitled4/cmake-build-debug --target untitled4 -- -j 1
[ 50%] Building CXX object CMakeFiles/untitled4.dir/main.cpp.o
/home/kugaz/CLionProjects/untitled4/main.cpp: In function ‘int main()’:
/home/kugaz/CLionProjects/untitled4/main.cpp:44:49: error: cast from ‘int*’ to ‘int’ loses precision [-fpermissive]
          << reinterpret_cast<int >(&osiedle[112])
                                                 ^
/home/kugaz/CLionProjects/untitled4/main.cpp:46:49: error: cast from ‘int*’ to ‘int’ loses precision [-fpermissive]
          << reinterpret_cast<int >(&osiedle[116])
                                                 ^
CMakeFiles/untitled4.dir/build.make:62: recipe for target 'CMakeFiles/untitled4.dir/main.cpp.o' failed
make[3]: *** [CMakeFiles/untitled4.dir/main.cpp.o] Error 1
CMakeFiles/Makefile2:104: recipe for target 'CMakeFiles/untitled4.dir/all' failed
make[2]: *** [CMakeFiles/untitled4.dir/all] Error 2
CMakeFiles/Makefile2:116: recipe for target 'CMakeFiles/untitled4.dir/rule' failed
make[1]: *** [CMakeFiles/untitled4.dir/rule] Error 2
Makefile:131: recipe for target 'untitled4' failed
make: *** [untitled4] Error 2

Dodatkowo mam zainstalowany na tym systemie codeblocks i wynik jest podobny. Krzyczy mi że w operatorze jest bład. Na chwile obecną szukam zrozumienia dlaczego tak się dzieje.

Alternatywne podejście (zamieniam int na intptr_t) zastosowane przeze mnie podaje w poniższym kodzie:

#include <iostream>
using namespace std;
#include <new>
                                //1

/*************************************************************/
int main()
{   // wstepna rezerwacja duzego obszaru pamieci, czyli kupujemy grunt na osiedle domow
    int *osiedle = new int[5000];                   //2
    //niwelowanie zdobytego obszaru
    for(int i = 0; i < 5000; i++) osiedle[i] = 1;   //3

    //teraz na tym terenie mozemy tworzyc obiekty, umieszczenie obiektu
    void *gdzie = &osiedle[102];                    //4
    int *wskint = new (gdzie) int;                  //5
    // -- praca nad tym obiektem --
    *wskint = 222;                                  //6
    cout << "*wskint = " << (*wskint) << endl;

    //==============================================================
    gdzie = &osiedle[102];
    int * wTabi = new (gdzie) int[3];                //7

    // praca z ta tablica
    for(int m = 0; m < 3; m++)
    {
        wTabi[m] = 1000 + m;
        cout << "wTabi[" << m << "] = " << wTabi[m] << " ";
    }
    cout << endl;
    //==============================================================
    gdzie = &osiedle[106];
    double * wTabd = new (gdzie) double[3];          //8

    // praca z ta tablica
    for(int n = 0; n < 3; n++)
    {
        wTabd[n] = 1 + ( 0.1 * n);
        cout << "wTabd[" << n << "] = " << wTabd[n] << " ";
    }
    cout << endl;
    //w miejscu o adresie podanym liczbowo===========================
    cout << "napisz jakis adres pomiedzy: "
         << reinterpret_cast<intptr_t >(&osiedle[112])
         << " - "
         << reinterpret_cast<intptr_t >(&osiedle[116])
         << "\na ja tam zbuduje ci obiekt: ";

    int adres;
    cin >> adres;
    gdzie = reinterpret_cast<void *>(adres);        //10
    int * wskA = new (gdzie) int;                   //11

    //---praca z tym obiektem----
    *wskA = 114;
    cout << "Wartosc = " << (*wskA) << endl;

    //===============================================================
    cout << "zobaczymy na te dzialke \n";           //12
    for(int k =99; k < 116; k++)
        cout << "[" << k << "]=" << osiedle[k] << endl;

    delete [] osiedle;
    //system("pause");
    //return 0;

}

Efekt skompilowania tego kodu jest połowiczny, jestem w stanie napisać numer obiektu. Natomiast jest bład tego rodzaju, że jak dobrze zrozumiałem to program konczy pracę z automatu ponieważ nie wystarcza mu pamięci na przeprowadzenie operacji.

/home/kugaz/CLionProjects/untitled4/cmake-build-debug/untitled4
*wskint = 222
wTabi[0] = 1000 wTabi[1] = 1001 wTabi[2] = 1002 
wTabd[0] = 1 wTabd[1] = 1.1 wTabd[2] = 1.2 
napisz jakis adres pomiedzy: 93833428454880 - 93833428454896
a ja tam zbuduje ci obiekt: 93833428454881

Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

To wszystko tyczyło się Linuxa zainstalowanego na wirtualnej maszynie. Natomiast do swoich codziennych zajęc, tam pracy i rozrywki korzystam z Windowsa 7. Na nim z ciekawości zainstalowałem sobie Microsoft Visual Studio 2012. Na którym kod z książki Symfonia C++ już jest kompilowany poprawnie.

Chciałbym prosić o sugestie czy podesłanie dodatkowych materiałów abym mógł lepiej opanować to zagadnienie.

Z poważaniem,

Kugaz

PS. Dziękuje że wytrwałeś do samego końca i przeczytałeś ten elaborat.

 

2 odpowiedzi

+1 głos
odpowiedź 10 maja 2017 przez adrian17 Ekspert (344,860 p.)

ponieważ nie wystarcza mu pamięci na przeprowadzenie operacji.

SEGV to Segmentation Fault, zazwyczaj spowodowany próbą użycia pamięci z obszaru nie należącego do programu.

Na chwile obecną szukam zrozumienia dlaczego tak się dzieje.

To proste. Na Twojej platformie wskaźniki mają 64 bity, a int ma 32 bity. Więc próba konwersji wskaźnika na int pewnie nie da tego co byś chciał, podobnie konwersja w drugą stronę.

Dlatego właśnie "poprawiony" kod wciąż nie działa:

    int adres;
    cin >> adres;
    gdzie = reinterpret_cast<void *>(adres);   

Program oczekuję liczbę 32-bitową, próbuje ją wczytać, po czym próbujesz ją potraktować jako 64-bitowy wskaźnik. Dostajesz śmieć.

Rozwiązaniem jest po prostu zmiana int na intptr_t.

W MSVC działało Ci to pewnie dlatego, że tam domyślnie kompiluje się w trybie 32-bitowym. Jeśli zmienisz trub kompilacji na 64-bitowy (dropdown na górnym pasku z tekstem "x86"), pewnie dostaniesz podobny problem.

komentarz 10 maja 2017 przez Kugaz Nowicjusz (120 p.)

Dziękuje za odpowiedź smiley

0 głosów
odpowiedź 10 maja 2017 przez j23 Mędrzec (194,920 p.)

reinterpret_cast<int >(&osiedle[112])

W trybie 64-bitowym typ int może być 32-bitowy, wskaźniki zawsze są 64-bitowe. Stąd ten błąd.

Podobne pytania

–1 głos
1 odpowiedź 713 wizyt
0 głosów
0 odpowiedzi 546 wizyt
0 głosów
1 odpowiedź 812 wizyt

92,555 zapytań

141,402 odpowiedzi

319,541 komentarzy

61,939 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...