web-dev-qa-db-fra.com

conversion obsolète de constante de chaîne en 'char *'

Dupliquer possible:
Conversion obsolète en C++ de constante de chaîne en 'char *'

Je veux passer une chaîne via char * à une fonction.

 char *Type = new char[10];
 Type = "Access";  // ERROR

Cependant, j'obtiens cette erreur:

 error: deprecated conversion from string constant to 'char*'

Comment puis-je résoudre ce problème?

26
mahmood

Si vous voulez vraiment modifier le type:

char *Type = new char[10];
strcpy( Type, "Access" );

Si vous ne souhaitez pas modifier l'accès:

const char *Type = "Access";

Notez cependant que les tableaux de caractères en C et en C++ posent de nombreux problèmes. Par exemple, vous ne savez pas vraiment si l'appel à new a réussi ou s'il va déclencher une exception. En outre, strcpy () pourrait dépasser la limite de 10 caractères.

Vous pouvez donc envisager, si vous souhaitez modifier le type ultérieurement:

std::string Type = "Access";

Et si vous ne voulez pas le modifier:

const std::string Type = "Access";

... L'avantage d'utiliser std::string est qu'il est capable de gérer tous ces problèmes.

38
Baltasarq

Il y a quelques choses qui se passent ici.

char *Type = new char[10];

Cela crée un pointeur char* nommé Type et l'initialise pour pointer vers le premier élément d'un tableau à 10 éléments récemment alloué.

Type = "Access";  // ERROR

Cette cession ne fait pas ce que vous pensez. Il ne copie pas la chaîne de 6 caractères "Access" (7 caractères, y compris le '\0' final) dans le tableau que vous venez de créer. Au lieu de cela, il assigne un pointeur au premier élément de ce tableau dans votre pointeur Type. Cela pose deux problèmes.

Premièrement, il écrase la valeur précédente de Type. Ce tableau de 10 caractères que vous venez d'allouer n'a rien qui le pointe; vous ne pouvez plus y accéder ni même le désallouer. Ceci est une fuite de mémoire.

Ce n'est pas ce dont se plaint le compilateur.

Deuxièmement, un littéral de chaîne crée un tableau const alloué statiquement ("alloué statiquement" signifiant qu'il existe pour toute l'exécution de votre programme). Type n'est pas déclaré avec un qualificatif const. Si le compilateur vous a permis de pointer Type vers la chaîne "Access", vous pouvez utiliser ce pointeur pour (tenter de) le modifier:

Type = "Access";
Type[0] = 'a'; // try to change the string to "access"

const a pour but de vous empêcher de modifier, voire de tenter de modifier, des éléments en lecture seule. C'est pourquoi vous n'êtes pas autorisé à affecter une valeur de pointeur non-const à un objet pointeur const.

Puisque vous programmez en C++, il vaut probablement mieux utiliser std::string.

12
Keith Thompson

Je veux passer une chaîne via char * à une fonction.

Voici comment vous pouvez passer une chaîne via char * à une fonction (notez le mot clé const requis dans la signature de la fonction.)

#include <iostream>
void f(const char* p) {
  std::cout << p << "\n";
}

int main() {
  f("Access");
}

Mais que se passe-t-il si vous appelez une fonction existante et ne pouvez pas modifier sa signature?

Si vous avez une garantie externe que la fonction n’écrira pas par son pointeur d’argument,

#include <iostream>
void f(char* p) {
  std::cout << p << "\n";
}

int main() {
  f(const_cast<char*>("Access"));
}

Si, par contre, la fonction peut écrire dans la chaîne, vous devrez alors allouer de l'espace pour la chaîne:

#include <iostream>
void f(char* p) {
  *++p;
  std::cout << p << "\n";
}

int main() {
  // Allocate read-write space on the heap
  char *p = new char[strlen("Access"+1)];
  // Copy string to allocated space
  strcpy(p, "Access");
  f(p);
  delete p;
}

ou, 

#include <iostream>
void f(char* p) {
  *++p;
  std::cout << p << "\n";
}

int main() {
  // Allocate read-write space on the stack
  char arr[] = "Access";
  f(arr);
}

Mais le mieux est de loin d'éviter tout le pointeur mishegas:

#include <iostream>
void f(const std::string& p) {
  std::cout << p << "\n";
}

int main() {
  f("Access");
}
5
Robᵩ

Vous avez un problème d'opération de base ici, pas un problème de codage. 

Lorsque vous souhaitez modifier le contenu d'un tableau de caractères C, vous n'utilisez pas l'opérateur d'affectation . Cela changera plutôt la valeur du pointeur sous-jacent. Ick.

Au lieu de cela, vous êtes censé utiliser les routines de la bibliothèque de chaînes de caractères C. Par exemple, strcpy (Type, "Access"); copiera le littéral de chaîne "Access" dans votre tableau de caractères, avec son tout dernier caractère nul.

Si vous utilisez C++ (comme l'indiquent vos balises), vous devriez probablement utiliser std::string au lieu de tableaux de caractères. La cession fonctionne comme vous le souhaitez.

0
T.E.D.