2013-08-05 3 views
1

J'ai essayé de convertir un char const en char au cours des 30 dernières minutes. Voici ce que j'ai.Exception non gérée lors de la conversion de const char en char

string atr; 

getline(cin,atr); // Start off with a string because getline takes nothing else. 
const char *buffA = atr.c_str(); // Create a const char of the string converted to a const char. 
char *buff = ""; // Create a new char to hold the converted result. 
strcat(buff,buffA); // Do the conversion. 
parseargs(buff); // Pass the data on. 

Cependant, j'obtiens une exception non gérée. Je ne sais pas pourquoi. J'ai littéralement tapé 'essayer' dans la console comme seul argument.

+7

«J'ai essayé de convertir un const char à un char » NON NON NON NON NON NON. Arrête de vouloir ça. Dites-nous ce que vous essayez de faire que vous croyez serait fait en convertissant un char const en char. Décrivez votre problème, pas simplement votre solution. –

+0

Mais pourquoi n'utilisez-vous pas directement la chaîne? – Nbr44

+0

Je vous recommande de prendre [un bon livre d'introduction C++ (cliquez sur ce lien pour une liste)] (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) Vous pouvez donc apprendre des techniques C++ modernes qui rendraient votre code beaucoup plus compréhensible, concis et sûr. Comme vous pouvez le voir dans [la réponse de Nightcracker] (http://stackoverflow.com/a/18054812/308661), votre code peut être réécrit avec moins de lignes et fonctionne réellement. –

Répondre

5

Il y a deux choses qui ne vont pas avec votre code. Tout d'abord, vous initialiser un char* avec un littéral de chaîne. Cela utilise une conversion obsolète; le type d'une chaîne littérale est char const[] (qui se transforme en char const*, sans char*), parce que toute tentative visant à modifier le comportement littéral est indéfini. La seconde est que votre littéral de chaîne est seulement un char long, donc même si vous pouviez écrire, sauf si atr était vide, vous êtes écriture au-delà de la fin de la mémoire tampon.

Vous ne nous dites rien sur parseargs. Si ce n'est pas modifier son argument, vous pouvez simplement le passer atr.c_str(), et être fait avec elle. (Si c'est une fonction héritée qui ignore const, vous devrez peut-être utiliser un const_cast ici.) Si elle ne modifie son argument (disons parce qu'il utilise strtok), alors vous devrez pousser explicitement une '\0' sur la fin de atr, et passez ensuite &atr[0]. (Pas une solution particulièrement propre, mais si vous ne l'utilisez atr après, il devrait fonctionner.)

+0

Merci pour cette réponse extrêmement utile! – Daaksin

4

Vos contenus de buff et buffA sont tous deux en mémoire du processus en lecture seule.
Vous aurez besoin réellement new votre buff comme

char* buff = new char[32]; 

Ceci fournit la mémoire de la libre magasin et vous pouvez alors strcat la chaîne buffA-buff. Vous devriez préférer strncat, mais pour éviter les dépassements de tampon et delete votre buff finalement.

+0

Oh! Bien, merci beaucoup pour cette réponse. J'oublie continuellement qu'en C++ vous devez assigner de la mémoire à vos variables. Eh bien, de toute façon, applaudissements! – Daaksin

+0

Vous êtes les bienvenus, mais s'il vous plaît ne oubliez pas de faire la distinction entre les tas et les variables à base de pile (considérer, tableaux, aussi) !! –

+0

@Daaksin En plus de cela, il vaudrait mieux que vous utilisiez simplement 'string' au lieu de convertir' char * 'en premier lieu. – Hulk

8

Essayez d'utiliser C++ au lieu de idiomes C:

std::vector<char> data(atr.begin(), atr.end()); 
data.push_back('\0'); 
parseargs(&data[0]); 
+0

Fermez. Comme écrit, c'est probablement un comportement indéfini: puisque 'parseargs' ne prend pas de longueur, il attend presque certainement une chaîne terminée par '' \ 0 ''. Vous devez donc repousser un «\ 0» avant de passer '& data [0]'. (Bien sûr, si 'parseargs' ne modifie pas son argument,' atr.c_str() 'résout le problème complètement, il est probable qu'il n'y ait pas besoin de copie de toute façon.) –

+0

@JamesKanze: Bonne prise! – orlp

+0

Directement au but! Merci pour l'extrait de code, nightcracker! – Daaksin

2

Ce

char *buff = ""; // Create a new char to hold the converted result. 

crée un char * qui pointe (lecture seule sans doute) mémoire d'environ 1 octet dans mesure. Ce:

strcat(buff,buffA); // Do the conversion. 

tentatives de Écraser (lecture seule sans doute) mémoire de 1 ou octets ainsi avec une chaîne arbitraire.

Les chances sont que cela se bloque rapidement. Si la mémoire est en lecture seule, elle se bloque immédiatement. Si la mémoire n'est pas en lecture seule, elle écrase les données aléatoires, ce qui entraîne un comportement très indéfini.

Pourquoi diable voulez-vous faire cela? Est-ce que parseArgs a réellement besoin d'une chaîne modifiable? C'est analyser les arguments, il ne devrait pas avoir besoin de les changer. Si c'est vraiment nécessaire, utilisez un std::vector<char> et passez l'adresse du premier élément et espérons que tout ce qu'il fait est de piquer le contenu du tableau, plutôt que de (disons) courir sur la fin.

+0

Très bien expliqué, merci pour cela! – Daaksin

Questions connexes