2010-10-23 8 views
1

Possible en double:
What's the difference between new char[10] and new char(10)ce qui est différent entre char * t = new char et char * t = new char [10];

ce qui est différent entre

char* t1=new char 

et

char* t2=new char[10]; 

à la fois allouer de la mémoire et t1 [100] = 'm' et t2 [100] = 'm' est correct pour les

----------- après modification:

mais pourquoi nous pouvons utiliser t1 [100] si t1 est alloué dynamiquement char pas tableau de char

+0

Qu'entendez-vous par "t (x) [100] = 'm' est correct pour eux"? C'est juste une coïncidence que vous pouvez définir cette mémoire sur 'm' sans que votre programme plante. Vous n'avez pas alloué cette mémoire de sorte que vous écrivez la fin du tableau dans la mémoire qui pourrait être n'importe quoi. –

+1

Fondamentalement une copie de: http://stackoverflow.com/questions/3902011/whats-the-difference-between-new-char10-and-new-char10, sauf pour ce dernier commentaire dans votre question. 't [100] = 'm'' est bien formé, mais conduit à un comportement indéfini dans les deux cas. Ne pas. – GManNickG

+1

Vous pouvez utiliser 't1 [100]' car lorsque X est un pointeur, X [I] 'est équivalent à' * (X + I) '. Vous déplacez simplement la valeur du pointeur sur 100 éléments et déréférencer. C++ ne se soucie pas ou n'essaye pas de protéger le programmeur de faire des choses stupides. C'est à vous. – GManNickG

Répondre

0

t1 pointe vers un caractère dynamiquement alloué; t2 pointe vers un tableau alloué dynamiquement de 10 caractères. Mais je crois que c'est C++, pas C. Et c'est certainement un doublon.

Révision après modification de l'OP p [n] où p est un pointeur et n est un entier est équivalent à * (p + n) donc il est comme l'accès à 100 caractères loin de ce que vos p points à. Dans les deux cas (t1 et t2), le 100ème (101ème) élément est hors de votre propriété, donc c'est UB. En fait, le fait ci-dessus rend légal d'écrire 2[array] interchangeable avec array[2]. Fantaisie, mais ne pas le faire :)

3

Vous devez delete ces différentes puisque les tableaux sont attribués en utilisant une autre variante de operator new:

delete t1; 
delete [] t2; 
4

Votre premier cas crée un seul élément char (1 octet) alors que votre deuxième cas crée 10 éléments consécutifs char (10 octets). Cependant, votre accès au t(x)[100]='m' n'est pas défini dans les deux cas. C'est-à-dire que vous demandez 100 octets après la position du pointeur, ce qui est probablement une donnée erronée. En d'autres termes, votre affectation de 'm' remplacera tout ce qui existe déjà, ce qui pourrait être des données d'un autre tableau. Ainsi, vous pouvez rencontrer des erreurs bizarres pendant l'exécution. C/C++ permet aux programmeurs d'accéder à des tableaux hors des limites car un tableau n'est en fait qu'un pointeur sur la mémoire consécutive. La convention t1[100] est juste 100 octets après le pointeur, peu importe ce que c'est.

Si vous voulez des tableaux "sûrs", utilisez la classe vector et appelez la fonction at(). Cela lancera l'exception out_of_range si l'accès est invalide.

Stroustrup donne l'exemple suivant:

template<class T> class Vec : public vector<T> { 
public: 
    Vec() : vector<T>() {} 
    Vec(int s) : vector<T>(s) {} 

    T& operator[] (int i) {return at(i);} 
    const T& operator[] (int i) const {return at(i);} 
}; 

Cette classe est limite de sécurité.Je peux l'utiliser comme ceci:

Vec<char> t3(10);    // vector of 10 char elements 
try { 
    char t = t3[100];   // access something we shouldn't 
} 
catch (out_of_range) { 
    cerr << "Error!" << endl; // now we can't shoot ourselves in the foot 
}