int main()
{
char *name = new char[7];
name = "Dolphin";
cout << "Your name is : " << name <<endl;
delete [] name;
}
Warum beschwert sich der VC++-Compiler nicht?
int main()
{
char *name = new char[7];
name = "Dolphin";
cout << "Your name is : " << name <<endl;
delete [] name;
}
Warum beschwert sich der VC++-Compiler nicht?
Sie haben hier zwei Fragen:
Erstens: Was ist falsch am Code? Nun ...
Wenn Sie "Dolphin" dem Namen zuweisen, kopieren Sie nicht in das zugewiesene Array, sondern passen den Zeiger so an, dass er auf ein Stringliteral zeigt. Später versuchen Sie zu löschen, worauf der Zeiger zeigt. Ich würde erwarten, dass dies in einigen Umgebungen schrecklich abstürzen wird.
Wenn Sie wirklich eine Kopie der "Dolphin"-Zeichen wollen, schauen Sie sich strncpy() an, aber wie bereits erwähnt, brauchen Sie auch ein Leerzeichen für die Null.
Zweitens, warum dieser bestimmte Compiler Sie nicht warnt, dass die Zuweisung potenziell ist: Das ist etwas schwieriger. [Die Frage ist, ob dieser Compiler ein String-Literal als "Zeiger auf const char" oder als "Zeiger auf char" behandelt.
Wenn es der erste Fall wäre, würde ich einen Fehler erwarten. Bis etwa 2004 war C++ konsistent mit C bei der Behandlung Literale als Zeiger auf char, und damit die Zuordnung wäre zulässig. Die Frage, die sich Ihnen stellt, ist also, mit welcher Version der Spezifikationen Sie arbeiten, und das könnte von der Version von VC++ abhängen, die Sie verwenden, und auch von den Compileroptionen, die Sie gewählt haben.
A MSDN C++ Referenz zeigt an, dass VC++ String-Literale als nicht konstant behandelt. Ich überlasse es den VC++-Gurus, weitere Kommentare abzugeben.
const char *name = "Dolphin"
(keine Zuweisung erforderlich!) und NICHT LÖSCHEN oder verwenden strcpy
um den Text in den neu zugewiesenen Bereich zu kopieren - den Sie später löschen.Sie können ein String-Literal ("Dolphin"), das sich im Nur-Lese-Speicher befindet, nicht löschen. Auch in diesem Sinne - wenn Sie schreiben name = "Dolphin"
Sie weisen den Zeiger neu zu, was bedeutet, dass der ursprünglich zugewiesene Speicher verloren geht.
iostream
und erklärte, dass Sie using namespace std;
während Sie cout und cin verwenden, die darin definiert sind,name
auf einen Speicher verweist, wenn Sie ein Zeichenfolgenliteral zuweisen, weisen Sie tatsächlich einen Zeiger darauf zu und verlieren so den Zeiger auf die 7 zuvor zugewiesenen Bytes,Zwei korrekte Vorgehensweisen wären hier zu nennen:
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char *name = new char[8];
strcpy(name, "Dolphin");
cout << "Your name is : " << name <<endl;
delete [] name;
return 0;
}
Denken Sie daran, dass Sie zum Speichern von "Dolphin" 8 Bytes benötigen, wobei 1 Byte für das NUL-Zeichen vorgesehen ist. Die zweite Version (mehr C++):
#include <iostream>
#include <string>
using namespace std;
int main()
{
string name = "Dolphin";
cout << "Your name is : " << name <<endl;
return 0;
}
Und diese braucht nicht gelöscht zu werden.
Der Grund, warum sich der Compiler nicht beschwert, ist einfach, dass der Compiler nicht für Sie auf Speicherlecks prüft. Dafür gibt es andere Programme, zum Beispiel valgrind. Der Compiler wird sich auch nicht über das Löschen des Speichers des String-Literales beschweren, weil er nicht analysiert, was Sie mit dem Zeiger gemacht haben, seit Sie ihm die Adresse eines String-Literales zugewiesen haben, so dass er nicht wissen kann, dass er sich seither nicht geändert hat.
const char* name;
ist ausreichend. Wenn Sie dem Namen "Dolphin" zuweisen, ändert sich der Wert des Zeigers. Schließlich wird der delete[] name
ist falsch. Es wird versucht, die Konstante char* "Dolphin" zu löschen, die nicht auf dem Heap alloziert ist.
Der gesamte Code könnte also lauten
int main()
{
const char *name;
name = "Dolphin";
cout << "Your name is : " << name <<endl;
}
Der Compiler beschwert sich nicht, da Ihr Code nicht gegen die Grammatik von C++ verstößt
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
10 Stimmen
Sie sollten Folgendes verwenden
std::string
die solche Dinge zulässt.4 Stimmen
Er beschwert sich nicht, weil bei C/C++-Programmierern davon ausgegangen wird, dass sie wissen, was sie tun. Auf "name" irgendwo anders hinzuweisen ist völlig legal. Obwohl ich in diesem Fall erwarten würde, dass GCC eine Warnung ausgibt, weil Sie einen (char *) Zeiger für den Zugriff auf den konstanten Abschnitt verwenden. Ich kenne mich mit VC++ nicht aus. Wenn Sie nichts sagen, gibt main() 0 zurück.
1 Stimmen
Warum sollte sie sich beschweren? Sie tun nichts Illegales, soweit es den Compiler betrifft. Compiler sind nicht telepathisch, sie wissen nicht, was Sie tun wollten, im Gegensatz zu dem, was Sie tatsächlich getan haben.
0 Stimmen
Gcc: Warnung: Veraltete Konvertierung von String-Konstante nach 'char*'