Pourquoi est main() argument argv de type char*[] plutôt que de const char*[]?
Quand j'ai écrit le code suivant et exécuté, le compilateur dit
obsolète conversion de chaîne de caractères constante de
char*
int main()
{
char *p;
p=new char[5];
p="how are you";
cout<< p;
return 0;
}
Cela signifie que je l'aurais écrit const char *
.
Mais quand on passe des arguments dans main
à l'aide de char* argv[]
nous ne pas écrire const char* argv[]
.
Pourquoi?
- Ok, mais pourquoi est-elle nécessaire pour char* être constante tout en l'affectant à une chaîne de caractères?
- Votre question est intéressante, mais le code jusqu'à il n'est pas pertinent. Si vous êtes autorisé à céder les littéraux de chaîne pour non-coût des pointeurs n'a rien à voir avec le type de paramètre de
main
. (Aussi, votre code de fuites de mémoire.) - Quelque chose d'autre que vous avez négligé: Nous n'avons pas de passer des arguments dans
main
. Il est illégal d'appelermain
de l'intérieur de votre programme. L'appel demain
est quelque chose que votre compilateur met en place pour vous; vous n'êtes pas autorisé à le faire vous-même. - Aussi, je crois que vous êtes juste de gaspiller de la mémoire avec la
new
appel. La chaîne rassemble c'est le propre de la mémoire de la pile. - Vous faire passer des paramètres à la main. Juste pas directement. Mais ce sont les mêmes paramètres que vous passez à
execve
et des fonctions similaires. - Hey merci les gars, ya nous passer des paramètres à la main à partir de la borne de droite?
- Mais vous n'êtes pas le passage d'un
const char*
, vous êtes en passant une série de caractères. Même si la plate-forme transmet les paramètres pour le programme dans la mémoire en lecture seule, beaucoup d'étapes avant d'arriver à votre programme entremain
, dont un qui peut facilement être "copier les paramètres quelque part je peux écrire pour eux." - Il y a une fuite de mémoire dans votre exemple
Vous devez vous connecter pour publier un commentaire.
Parce que ...
argv[]
n'est pas const. Et il n'est certainement pas un (statique) chaîne de caractères littérale puisque c'est en cours de création au moment de l'exécution.Vous êtes à la déclaration d'une
char *
pointeur puis l'affectation d'une chaîne littérale, qui est par définition constante; les données sont en lecture seule mémoire.D'entrée:
De sortie:
Ce n'est pas un commentaire sur pourquoi vous voulez changer
argv
, mais il est certainement possible.argv
si vous acceptez toutes les données sensibles comme les paramètres du programme.Des raisons historiques. La modification de la signature de main() de casser trop de code existant. Et il est possible que certaines implémentations vous permettent de modifier les paramètres à la main à partir de votre code. Cependant le code comme ceci:
est toujours illégal, parce que vous ne sont pas autorisés à jouer avec les littéraux de chaîne comme ça, si le pointeur doit être à un const char.
main()
est faux.main()
simplement ne peut pas être invoquée à l'aide des constantes de chaîne, donc il n'y a aucune raison pour que les paramètres soientconst
. Voir ma réponse.argv[]
est une technique courante. Il est effectivement nécessaire que si vous acceptez toutes les données sensibles en tant que paramètres. Par conséquent, la raison n'est pas historique, il n'aurait tout simplement pas de sens si vous ne pouvais pas le faire.argv
garantie pour éviter l'original d'être visible à travers procfs ou d'un autre mécanisme?Parce que ces chaînes littérales (comme
"hi"
,"hello what's going on"
, etc), sont stockés dans le en lecture seule segment de votre exe. En tant que tel, les pointeurs qui pointent vers leur point de constante caractères (par exemple, ne peut pas les modifier).De l'affectation d'une chaîne de caractères constante (
const char*
) à un pointeur vers un non-constante chaîne de caractères (char *p
). Cela vous permettra de modifier la constante de chaîne, par exemple en faisantp[0] = 'n'
.De toute façon, pourquoi n'utilisez-vous pas
std::string
à la place ? (vous semblez être à l'aide de C++).Si vous regardez l'exécution des fonctions comme
execve
, vous verrez qu'ils n'ont pas réellement accepterconst char*
paramètres, mais ne sont en effet exigerchar*
, par conséquent, vous ne pouvez pas utiliser une constante de chaîne d'invoquermain
.main
à tous.const
. Ce qui n'est pas un problème, car la mémoire de l'exécution des processus est distincte de celle de la one, donc les choses devront être copiée, en tout cas.