• 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]

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
0 głosów
3,401 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 Mentor (351,140 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 (195,260 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ź 840 wizyt
0 głosów
0 odpowiedzi 704 wizyt
0 głosów
1 odpowiedź 862 wizyt

93,190 zapytań

142,204 odpowiedzi

322,030 komentarzy

62,518 pasjonatów

Advent of Code 2024

Top 15 użytkowników

  1. 2817p. - dia-Chann
  2. 2769p. - Łukasz Piwowar
  3. 2759p. - Łukasz Eckert
  4. 2738p. - CC PL
  5. 2704p. - Tomasz Bielak
  6. 2678p. - Łukasz Siedlecki
  7. 2666p. - rucin93
  8. 2485p. - Marcin Putra
  9. 2418p. - Michal Drewniak
  10. 2367p. - Adrian Wieprzkowicz
  11. 2317p. - Mikbac
  12. 2239p. - Michał Telesz
  13. 2156p. - Anonim 3619784
  14. 1733p. - rafalszastok
  15. 1628p. - Dominik Łempicki (kapitan)
Szczegóły i pełne wyniki

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

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...