2017-10-09 5 views
1

Je suis curieux de savoir pourquoi ces deux morceaux de code donnent une sortie différentePourquoi le pointeur sur un char se comporte-t-il différemment d'un pointeur sur un char en tant qu'élément de tableau?

#include <iostream> 
using namespace std; 
int main(){ 
    char *arr=new char; 
    arr="monday"; 
    cout<<arr<<endl;//gives the output "monday" 

    char *newArr=new char[3];//i want array of three pointers not the size of a string to be 2+1 
    newArr[0]="monday";//err 
    cout<<newArr[0]<<endl; 


    system("pause"); 
    return 0; 

} 

je veux dire qu'ils ne sont pas les deux conseils pour aborder la première lettre

la question est quelle est la différence entre « arr » et "newArr [0]"

Répondre

5

vous avez plus de mal que vous vous rendez compte ...

Avec

char *arr=new char; 
arr="monday"; 

vous faites d'abord arr pointer sur un seul caractère que vous allouez. Ensuite, vous réaffectez arr et faites-le pointer ailleurs (au premier caractère du tableau pour le littéral "monday"). Cela conduit à fuite que la mémoire d'origine que vous allouez est perdue et ne peut plus être consulté.

Quant à

char *newArr=new char[3]; 
newArr[0]="monday"; 

Ici vous faire newArr le point à un « tableau » de trois caractères simples, et puis essayer de faire le point de caractère newArr[0] à la chaîne littérale.


un peu différemment, ce que vous essayez de faire avec

char* arr = new char; 

est essentiellement équivalente à

char arr[1]; 

Et avec

char* newArr = new char[3]; 

C'est équivalent à

char newArr[3]; 

La norme façon de résoudre votre problème est bien sûr d'utiliser la classe standard C++ std::string. Comme par exemple

std::string arr; 
arr = "monday"; 

Et avec un std::vector ou std::array pour la seconde:

std::array<std::string, 3> newArr; 
newArr[0] = "monday"; 

Enfin, au sujet de la différence entre arr et newArr[0]. L'un est un pointeur vers char, de type char*. L'autre est un char (mais newArr est un pointeur vers char tout comme arr).

+0

pourquoi compilateur permet même de réassigner arr, si je peux demander – awashima

+1

@awashima Parce que ce n'est pas invalide? Vous pouvez le faire pointer vers n'importe où si vous le souhaitez. C++ ne tient pas la main, si vous voulez [vous tirer dans le pied] (http://idioms.thefreedictionary.com/shoot+in+the+foot) vous pouvez le faire. –

0

ne sont-ils pas tous les deux des pointeurs vers l'adresse de la première lettre?

Oui, les deux arr et newArr sont des pointeurs vers le premier caractère dans une chaîne C-style. Cependant, newArr[0] n'est pas du tout un pointeur, donc C++ ne vous laisse pas lui attribuer un pointeur const char*.

Si vous souhaitez obtenir un pointeur sur le caractère initial de newArr, vous devez utiliser l'opérateur &, c'est-à-dire &newArr[0]. Vous ne seriez pas en mesure de lui attribuer, mais vous seriez en mesure d'imprimer:

const char *newArr = "monday"; 
cout << newArr[0] << endl; // prints m 
cout << &newArr[0] << endl; // prints monday 

Notez que les deux missions de new dans vos produits de code fuites de mémoire, parce que vous écrasez la valeur produite par new entre eux sans libérer la mémoire allouée.

+0

delete arr; delete [] newArr; devrait être ajouté? – awashima

+0

@awashima Cela serait vrai si votre code utilisait les valeurs allouées de quelque façon que ce soit. Cependant, ce n'est pas le cas: vous remplacez immédiatement les pointeurs alloués. C'est pourquoi une meilleure alternative est de supprimer complètement 'new', car votre programme n'utilise pas ses résultats. – dasblinkenlight

+0

ok, je comprends, je voulais juste deux, ce qui me paraissait sémantiquement identique, morceaux de code ... mais si je fais quelque chose comme ça (assignation consistait à allouer dynamiquement array et le remplir avec des jours dans la semaine) {char (* arr) [12] = nouveau caractère [7] [12]; strcpy (arr [0], "lundi"); strcpy (arr [1], "mardi"); strcpy (arr [2], "mercredi"); strcpy (arr [3], "jeudi"); strcpy (arr [4], "vendredi"); strcpy (arr [5], "samedi"); strcpy (arr [6], "dimanche"); pour (int i = 0; i <7; i ++) {cout << arr [i] << endl; } delete [] arr;} sont les emplacements alloués au début utilisés avec strcpy() ou, je veux dire, il y a fuite de mémoire – awashima

0

Quelle est la différence entre "arr" et "newArr [0]"

Réponse courte, contrairement arr, newArr[0] n'est pas un pointeur, mais peut plutôt tenir un caractère. newArr[i] est identique à *(newArr + i). Vous essayez de placer une chaîne sur un type de caractère.