Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Recensione HUAWEI Mate X7: un foldable ottimo, ma restano i soliti problemi
Recensione HUAWEI Mate X7: un foldable ottimo, ma restano i soliti problemi
Mate X7 rinnova la sfida nel segmento dei pieghevoli premium puntando su un design ancora più sottile e resistente, unito al ritorno dei processori proprietari della serie Kirin. L'assenza dei servizi Google e del 5G pesa ancora sull'esperienza utente, ma il comparto fotografico e la qualità costruttiva cercano di compensare queste mancanze strutturali con soluzioni ingegneristiche di altissimo livello
Nioh 3: souls-like punitivo e Action RPG
Nioh 3: souls-like punitivo e Action RPG
Nioh 3 aggiorna la formula Team NINJA con aree esplorabili più grandi, due stili di combattimento intercambiabili al volo (Samurai e Ninja) e un sistema di progressione pieno di attività, basi nemiche e sfide legate al Crogiolo. La recensione entra nel dettaglio su combattimento, build, progressione e requisiti PC
Test in super anteprima di Navimow i220 LiDAR: il robot tagliaerba per tutti
Test in super anteprima di Navimow i220 LiDAR: il robot tagliaerba per tutti
La facilità di installazione e la completa automazione di tutte le fasi di utilizzo, rendono questo prodotto l'ideale per molti clienti. Ecco com'è andata la nostra prova in anteprima
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 10-08-2010, 06:19   #1
Q_Q
Member
 
Iscritto dal: Jan 2008
Messaggi: 103
[c++] puntatori

Codice:
struct _ARGB2
{
        byte R;
        byte G;
        byte B;
        byte A;
};

typedef _ARGB2* ArgbPtr;
Che differenza c'è tra questo:

Codice:
_ARGB2 (*_in)[640] = new _ARGB2[480][640];
e questo ?

Codice:
ArgbPtr *_inPtr = new ArgbPtr[480];
if (_inPtr != null)
{
    for (int i = 0; i < 480; i++)
        _inPtr[i] = new _ARGB2[640];
e com'è che vanno cancellati ?
Q_Q è offline   Rispondi citando il messaggio o parte di esso
Old 10-08-2010, 14:27   #2
fero86
Senior Member
 
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
questo:
Quote:
Originariamente inviato da Q_Q Guarda i messaggi
Codice:
_ARGB2 (*_in)[640] = new _ARGB2[480][640];
é sbagliato: il fatto che tu specifichi una costante numerica nella dichiarazione fa si' che l'array di primo livello venga allocato staticamente, quindi in quel caso devi solo allocare gli array di secondo livello.

l'altro invece é corretto ma il controllo dell'if é inutile perché l'operatore new non restituisce mai NULL (in caso di risorse di sistema insufficienti lancia un'eccezione C++ di tipo std::bad_alloc).

per quanto riguarda la deallocazione, il secondo va deallocato all'inverso del primo, cioé iterando sull'array di primo livello e facendo delete su ciascun array di secondo livello ed infine facendo delete sull'array di primo livello. il primo invece non lo so
forse devi fare:
Codice:
delete[][] _in;
ma sono andato ad ipotesi.
fero86 è offline   Rispondi citando il messaggio o parte di esso
Old 15-08-2010, 18:55   #3
Q_Q
Member
 
Iscritto dal: Jan 2008
Messaggi: 103
Ciao, grazie per la risposta
per il primo ho provato con delete [] [] _in; ma da errore, possibile che sia solo delete [] _in; ? perchè il [640] viene cancellato automaticamente ?
Q_Q è offline   Rispondi citando il messaggio o parte di esso
Old 15-08-2010, 19:31   #4
fero86
Senior Member
 
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
Quote:
Originariamente inviato da Q_Q Guarda i messaggi
per il primo ho provato con delete [] [] _in; ma da errore, possibile che sia solo delete [] _in; ? perchè il [640] viene cancellato automaticamente ?
si, puó essere ma ti confesso che non lo so proprio :|
la sintassi che hai usato tu, delete[] _in, si usa per deallocare gli array a una sola dimensione; forse si usa anche per quelli a piu dimensioni.
questa cosa interessa anche a me quindi se ho tempo provo a cercare qualcosa, altrimenti attendo con te un parere piu esperto.
fero86 è offline   Rispondi citando il messaggio o parte di esso
Old 15-08-2010, 21:02   #5
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da Q_Q Guarda i messaggi
Codice:
struct _ARGB2
{
        byte R;
        byte G;
        byte B;
        byte A;
};

typedef _ARGB2* ArgbPtr;
Che differenza c'è tra questo:

Codice:
_ARGB2 (*_in)[640] = new _ARGB2[480][640];
_in e' un puntatore ad arrays di 640 elementi che viene inizializzato
con un array che contiene 480 di tali elementi.

Quote:
Codice:
ArgbPtr *_inPtr = new ArgbPtr[480];
if (_inPtr != null)
{
    for (int i = 0; i < 480; i++)
        _inPtr[i] = new _ARGB2[640];
_inPtr e' un puntatore a puntatori, che viene inizializzato con un array di puntatori lungo 480. Ogni puntatore viene poi inizializzato con un array di 640 elementi.

La differenza fondamentale sta nella rappresentazione in memoria. Nel primo caso gli array stanno "tutti in fila" nell'array che li contiene, nel secondo caso hai invece dei soli puntatori.
Codice:
_in :
[[ .... ] [ ... ] [ ... ]]

_inPtr
[[  -  ][  -  ][  -  ]]
    |      |      |
  [...]  [...]  [...]
Se provi il seguente codice:
Codice:
    cout << "sizeof(_in)=" << sizeof(_in) << endl;
    cout << "sizeof(_in[0])=" << sizeof(_in[0]) << endl;

    cout << "sizeof(_inPtr)=" << sizeof(_inPtr) << endl;
    cout << "sizeof(_inPtr[0])=" << sizeof(_inPtr[0]) << endl;
Su una macchina a 32 bit otterrai il seguente output:
Codice:
sizeof(_in)=4
sizeof(_in[0])=2560
sizeof(_inPtr)=4
sizeof(_inPtr[0])=4
Quote:
e com'è che vanno cancellati ?
Per quanto visto sopra nel primo caso cancelli solo l'array piu' esterno, nel secondo caso anche quelli interni. Se la mia spiegazione ti ha confuso, segui un altro metodo infallibile: devi distruggere quello che hai allocato, per cui ad ogni new per un singolo oggetto corrisponde una delete, e ad ogni new per un array corrisponde una delete[].:

Codice:
delete [] _in;
for ( int i=0 ; < 480; ++i )
    delete [] _inPtr[i];
delete[] _inPTr;
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 15-08-2010, 21:07   #6
fero86
Senior Member
 
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
marco.r, si usa "delete[]" (con una sola coppia di parentesi quadre) anche quando con new si é allocato un array a due o piu dimensioni?
fero86 è offline   Rispondi citando il messaggio o parte di esso
Old 15-08-2010, 23:21   #7
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da fero86 Guarda i messaggi
marco.r, si usa "delete[]" (con una sola coppia di parentesi quadre) anche quando con new si é allocato un array a due o piu dimensioni?
Si', perche' per il C++ non si tratta di array a due dimensioni, ma normale.
La peculiarita' del primo e' che gli elementi sono un qualcosa di piu' corposo di un semplice int o float.
Visto che gli array contenuti si trovano "in linea" il compilatore non ha bisogno di far altro che usare la sua dimensione (che e' decisa staticamente e quindi conosce, in questo caso 2560, 640*4) per poter deallocare correttamente l'array puntato da _in;
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 15-08-2010, 23:40   #8
fero86
Senior Member
 
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
grazie
fero86 è offline   Rispondi citando il messaggio o parte di esso
Old 16-08-2010, 00:45   #9
tuccio`
Senior Member
 
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
Quote:
Originariamente inviato da marco.r Guarda i messaggi
Si', perche' per il C++ non si tratta di array a due dimensioni, ma normale.
La peculiarita' del primo e' che gli elementi sono un qualcosa di piu' corposo di un semplice int o float.
Visto che gli array contenuti si trovano "in linea" il compilatore non ha bisogno di far altro che usare la sua dimensione (che e' decisa staticamente e quindi conosce, in questo caso 2560, 640*4) per poter deallocare correttamente l'array puntato da _in;
mi verrebbe da chiedermi, non sapendo niente di c++, perché esista il delete[] allora, non basta delete? anche lì basta sapere il numero di byte da liberare
tuccio` è offline   Rispondi citando il messaggio o parte di esso
Old 16-08-2010, 01:22   #10
fero86
Senior Member
 
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
Quote:
Originariamente inviato da tuccio` Guarda i messaggi
mi verrebbe da chiedermi, non sapendo niente di c++, perché esista il delete[] allora, non basta delete? anche lì basta sapere il numero di byte da liberare
delete é diverso da delete[] perché se il blocco da cancellare é un array di oggetti devono essere invocati N distruttori, mentre se é un oggetto solo allocato dinamicamente deve essere invocato un distruttore solo.

le due delete in sostanza hanno una semantica diversa: delete senza parentesi quadre assume che tu gli abbia passato un blocco contenente un solo oggetto del tipo puntato, delete[] invece fa un calcolo di quanti oggetti di quel tipo sono contenuti nel blocco di memoria da liberare.

la spiegazione fa schifo ma spero che si comprenda.
fero86 è offline   Rispondi citando il messaggio o parte di esso
Old 16-08-2010, 01:25   #11
fero86
Senior Member
 
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
ecco, prova per esempio questo codice:
Codice:
#include <iostream>
using namespace std;

class C {
public:
  ~C() {
    cout << "farewell" << endl;
  }
};

int main() {
  delete new C[3];
  return 0;
}
taluni compilatori potrebbero generarti un eseguibile che stampa "farewell" una volta sola anziché 3. il codice corretto é questo:
Codice:
#include <iostream>
using namespace std;

class C {
public:
  ~C() {
    cout << "farewell" << endl;
  }
};

int main() {
  delete[] new C[3];
  return 0;
}
fero86 è offline   Rispondi citando il messaggio o parte di esso
Old 16-08-2010, 01:30   #12
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da tuccio` Guarda i messaggi
mi verrebbe da chiedermi, non sapendo niente di c++, perché esista il delete[] allora, non basta delete? anche lì basta sapere il numero di byte da liberare
Vero ho detto una cosa inesatta , in effetti pensandoci la ragione principale non e' tanto la memoria occupata (la free non ha bisogno di dimensioni...), quando la necessita' di sapere su quanti oggetti va chiamato il distruttore.
Faccio un esempio
Codice:
#include <iostream>

using namespace std;


struct Foo{ ~Foo(){ cout << "bye bye" << endl;}  };

int main()
{
    Foo* f1 = new Foo[10];
    Foo* f2 = new Foo[10];
    
    cout << "delete f1" << endl;
    delete f1;
    cout << "delete[] f2" << endl;
    delete[] f2;
}
L'output del programma e'
Codice:
delete f1
bye bye
delete[] f2
bye bye
bye bye
bye bye
bye bye
bye bye
bye bye
bye bye
bye bye
bye bye
bye bye
Il succo del discorso non cambia molto cmq. Nel caso del primo array iniziale, basta delete[] perche' gli array contenuti non devono liberare alcuna altra memoria, quella che occupano l'hanno "presa a prestito" dall'array che li contiene.
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 16-08-2010, 01:31   #13
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da fero86 Guarda i messaggi
delete é diverso da delete[] perché se il blocco da cancellare é un array di oggetti devono essere invocati N distruttori, mentre se é un oggetto solo allocato dinamicamente deve essere invocato un distruttore solo.

le due delete in sostanza hanno una semantica diversa: delete senza parentesi quadre assume che tu gli abbia passato un blocco contenente un solo oggetto del tipo puntato, delete[] invece fa un calcolo di quanti oggetti di quel tipo sono contenuti nel blocco di memoria da liberare.

la spiegazione fa schifo ma spero che si comprenda.
Ops, vedo ora che hai gia' risposto correttamente tu.
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 16-08-2010, 16:22   #14
Q_Q
Member
 
Iscritto dal: Jan 2008
Messaggi: 103
tnx
edit:
ah, secondo voi in un cellulare è meglio usare il primo o il secondo ( o non cambia nente da uno all'altro sui cell nuovi con trecentomillemiggglioni gb di ram ) ?

Ultima modifica di Q_Q : 16-08-2010 alle 16:26.
Q_Q è offline   Rispondi citando il messaggio o parte di esso
Old 16-08-2010, 21:01   #15
fero86
Senior Member
 
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
Quote:
Originariamente inviato da Q_Q Guarda i messaggi
tnx
edit:
ah, secondo voi in un cellulare è meglio usare il primo o il secondo ( o non cambia nente da uno all'altro sui cell nuovi con trecentomillemiggglioni gb di ram ) ?
dovresti mettere la semplicitá del codice prima della presunta efficienza: dal momento che conosci giá le dimensioni della matrice da allocare non serve allocarla dinamicamente, é meglio allocarla staticamente perché l'allocazione dinamica é piu difficile da gestire perché devi evitare il leak.

molto difficilmente avrai problemi di performance a causa di simili scelte, se ne dovessi mai avere é solo allora che dovrai refattorizzare, ammesso che la causa sia quella.
fero86 è offline   Rispondi citando il messaggio o parte di esso
Old 16-08-2010, 21:49   #16
marco.r
Senior Member
 
Iscritto dal: Dec 2005
Città: Istanbul
Messaggi: 1817
Quote:
Originariamente inviato da Q_Q Guarda i messaggi
tnx
edit:
ah, secondo voi in un cellulare è meglio usare il primo o il secondo ( o non cambia nente da uno all'altro sui cell nuovi con trecentomillemiggglioni gb di ram ) ?
E' piu' efficiente il primo metodo, perche' eviti una doppia dereferenziazione e quindi hai un accesso alla ram in meno. Questo vale tanto per il cellulare quanto per il pc desktop.
In generale se uno vuole evitare inefficiente, in C++ evita di allocare un doppio array in questo modo, piuttosto si crea una classe apposita che utilizzi un unico array.
Qualcosa tipo
Codice:
template <typename T>
class Matrix
{
    typedef T& reference;
    typedef const T& const_reference;

    Matrix(size_t rows,size_t cols ):_nRows(rows),_nCols(cols)
    {        
        _data = new value_type[rows*cols];
    }
    reference operator()(size_t row,size_t col)
    {
        assert( row <_nRows );
        assert( col < _nCols );
        return _data[ _nRows*col + row ];
    }
    const_reference operator()(size_t row, size_t col) const;
    // etc
private:
    size_t _nRows;
    size_t _nCols;
};
__________________
One of the conclusions that we reached was that the "object" need not be a primitive notion in a programming language; one can build objects and their behaviour from little more than assignable value cells and good old lambda expressions. —Guy Steele
marco.r è offline   Rispondi citando il messaggio o parte di esso
Old 16-08-2010, 22:12   #17
fero86
Senior Member
 
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
Quote:
Originariamente inviato da marco.r Guarda i messaggi
E' piu' efficiente il primo metodo, perche' eviti una doppia dereferenziazione e quindi hai un accesso alla ram in meno. Questo vale tanto per il cellulare quanto per il pc desktop.
si ma, ripeto, se le dimensioni sono note a priori (640x480) é inutile usare new e delete, basta semplicemente dichiarare la matrice:
Codice:
_ARGB2 _in[640][480];
cosi tra l'altro c'é un bel guadagno come tempi di esecuzione perché si evita la chiamata all'operatore new e successivamente quella all'operatore delete; a voler fare proprio i pignoli qualche millesimo di secondo secondo me lo risparmi
fero86 è offline   Rispondi citando il messaggio o parte di esso
Old 17-08-2010, 00:46   #18
Q_Q
Member
 
Iscritto dal: Jan 2008
Messaggi: 103
Quote:
Originariamente inviato da fero86 Guarda i messaggi
si ma, ripeto, se le dimensioni sono note a priori (640x480) é inutile usare new e delete, basta semplicemente dichiarare la matrice:
Codice:
_ARGB2 _in[640][480];
cosi tra l'altro c'é un bel guadagno come tempi di esecuzione perché si evita la chiamata all'operatore new e successivamente quella all'operatore delete; a voler fare proprio i pignoli qualche millesimo di secondo secondo me lo risparmi
c'è un problema (almeno con samsung bada non so con gli altri so per cellulari) se si fa così funziona solo nel simulatore e crasha sul telefono perchè l'array non sta nello stack
Q_Q è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Recensione HUAWEI Mate X7: un foldable ottimo, ma restano i soliti problemi Recensione HUAWEI Mate X7: un foldable ottimo, m...
Nioh 3: souls-like punitivo e Action RPG Nioh 3: souls-like punitivo e Action RPG
Test in super anteprima di Navimow i220 LiDAR: il robot tagliaerba per tutti Test in super anteprima di Navimow i220 LiDAR: i...
Dark Perk Ergo e Sym provati tra wireless, software via browser e peso ridotto Dark Perk Ergo e Sym provati tra wireless, softw...
DJI RS 5: stabilizzazione e tracking intelligente per ogni videomaker DJI RS 5: stabilizzazione e tracking intelligent...
Reddit punterà sull'AI per miglio...
Samsung ha obiettivi molto ambiziosi per...
I produttori non faranno sconti sulle me...
Ubisoft potrebbe cedere pezzi se il pian...
Qualcomm potrebbe utilizzare una tecnolo...
Starfield per Nintendo Switch 2 potrebbe...
Un MacBook Pro a -300€, i MacBook Air M4...
Amazon abbassa i prezzi sugli iPhone: sc...
Amazon, ancora sconti sugli smartphone A...
iPhone Air 2 'riciclerà' alcuni c...
Offerta Amazon da non perdere: lo speake...
Nioh 3 debutta alla grande su Steam: pri...
Al centro della Via Lattea ci potrebbe e...
Elon Musk ora guarda alla Luna: SpaceX p...
La Cina ha lanciato nuovamente lo spazio...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 21:43.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v