C++ Warum darf diese Char Variabel mehr als 1 bit haben und einen String aufnehmen?

obilaner

Lt. Junior Grade
Registriert
Apr. 2011
Beiträge
389
Hallo!

Ich möchte grade Klassen anhand eines Beispiels lernen, das ich nicht verstehe. Wieso wird der an die Methode übergebene Text in ein char Objekt gespeichert, obwohl es ein String ist? Dürfen char nicht eigentlich nur ein Bit speichern?

Falls der Code etwas verwirrt, die Comments sind nur Hilfsnotizen die ich mir gemacht habe, bitte ignorieren.
 

Anhänge

  • qSYgfn9.png
    qSYgfn9.png
    30,1 KB · Aufrufe: 335
Zuletzt bearbeitet:
Ich sehe da weder eine Klasse "Auto" noch die Instanz "Fahrzeug" sondern nur viel falsches C++ welches viele Fehler im Compiler erzeugt.

Hier wird nix in ein Char Objekt abgespeichert sonder in einen char Pointer, was kein C++ sondern C ist. Ein char Pointer wird auch gerne als "String" bezeichnet. Aber das ist eben kein C++.
 
Ich behaupte Stack, aber festlegen werde ich mich nicht :)
Und ja, das bringt in Zusammenhang mit einem Pointer gewisse Probleme mit sich.
 
So, habe das eben mal gegooglet: Stack Overflow meint an diversen Stellen, dass diese String literale static storage sind und sie im Read Only Datensegment abgelegt werden. Dadurch wird aber die gesamte Problematik nicht viel besser :). Denn beim Verändern des Strings oder beim Destruktur fliegt einem das immer noch um die Ohren.
 
Denn beim Verändern des Strings oder beim Destruktur fliegt einem das immer noch um die Ohren.
Beim Destruktor von was? Solange man nicht versucht, den Pointer zu delete[]n, passiert da eigentlich nicht viel.

Verändern können sollte man die natürlich nicht, String-Lite<rale sind eigentlich const char*. Normalerweise müsste der Compiler auch eine Warnung werfen, wenn man das an einen (veränderbaren) char* zuweist:
Code:
a.cpp:2:13: warning: conversion from string literal to 'char *' is deprecated [-Wc++11-compat-deprecated-writable-strings]

Ich behaupte Stack, aber festlegen werde ich mich nicht
Nai hat es ja schon beantwortet, aber ein (veränderbares) char-Array auf dem Stack ginge so:
Code:
char a[] = "Hallo.";
a[1] = 'e'; // Legaler Code
 
Zuletzt bearbeitet:
@ VikingGe
genau so meinte ich es aber da Strings als Membervariablen idr nicht Referenzen sondern ein "starker Besitz" sind, dessen Speicher man nach bei dem löschen idr auch wieder freigeben muss.
 
String literale static storage sind und sie im Read Only Datensegment abgelegt werden.

Ich hab bei meinen IDA Streifzügen noch kein ro Datensegment gesehen auch wenn dort nur Ressourcen und Strings abgelegt wurden.
 
HominiLupus schrieb:
Hier wird nix in ein Char Objekt abgespeichert sonder in einen char Pointer, was kein C++ sondern C ist. Ein char Pointer wird auch gerne als "String" bezeichnet. Aber das ist eben kein C++.

C++ ist das schon, wenn auch kein idiomatisches. Bitte Neulinge nicht mit unvollständigen / halbwahren Aussagen unnötig verwirren.
 
Sorry, hab da was für den Screenshot falsch zurückkopiert und war wohl etwas in Eile eben..

Screenshot_1.png

antred schrieb:
C++ ist das schon, wenn auch kein idiomatisches. Bitte Neulinge nicht mit unvollständigen / halbwahren Aussagen unnötig verwirren.

Juhu, danke, ich denke da hätt ich in den Datentypen (-Char) auch nicht viel zu gefunden.

Ich versuch dann erst einmal mir ein kleines funktionierendes Code Konstrukt zu basteln an dem ich mir die einfachen ein und Ausgaben in und aus einer Klasse einprägen kann. Finde irgendwie nur für mich verwirrende Beispiele.. Was einfaches mit Cout und Strings oder int würde ja schon reichen.

Muss ich nun tatsächlich einen Charpointer lernen und nutzen um einfache Strings in eine Klasse zu übergeben?
 
Zuletzt bearbeitet:
@Nai, @HominiLupus Hier unter Linux gibts das auch.
Code:
$ readelf --sections a.out

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  ...
  [14] .rodata           PROGBITS         00000000004006d0  000006d0
       000000000000002d  0000000000000000   A       0     0     4
  ...
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

Tatsächlich liegt der String des Testprogramms an Offset 0x4006db und beim Versuch, den zu verändern, gibts nen Segmentation Fault.
Wie es bei Windows und besonders bei der Microsoft-Toolchain ist? Keine Ahnung.

Nai schrieb:
genau so meinte ich es aber da Strings als Membervariablen idr nicht Referenzen sondern ein "starker Besitz" sind, dessen Speicher man nach bei dem löschen idr auch wieder freigeben muss.
Joa, stimmt schon. Es ist natürlich nicht die beste Idee, rohe char-Pointer durch die Gegend zu schieben, für sowas gibt es - @obilaner - std::string.
 
danke ich teste einfach mal rum :) Vieleicht klappts ja, sonst muss ich die Leiche hier die Tage nochmal ausgraben.

merci
 
Falls du an einer (einfachen) Möglichkeit interessiert bist das mit echten Strings zu machen:

Code:
#include <string>

class Auto
{
public:
	std::string Farbe;
	Auto(std::string farbe)//const & habe ich hier mal wegen Einfachheit weggelassen
	{
		Farbe = farbe;
	}

	void Fahre()
	{
		printf("%s", Farbe.c_str());
	}
};

int main(int argc, const char* argv[])
{
	Auto Fahrzeug("blau");
	Fahrzeug.Fahre();
	system("Pause");
	return 0;
}
 
Streiche lieber die Zeile mit dem printf und ersetze sie durch std::cout (hat der OP in seinem Beispiel ja ohnehin schon benutzt). Und verwende im Konstruktor statt Zuweisung lieber gleich Initialisierungslisten, wie es sich gehört.

Code:
class Auto
{
public:
	std::string Farbe;
	Auto(std::string farbe) : Farbe(farbe)
	{
	}
    
        // ...
 
Nai schrieb:
@ antred
Ich habe den Konstruktor bewusst so gewählt, weil diese Schreibweise einen einfacheren Syntax hat und es in diesem Fall sowieso mehr oder weniger egal ist.

Ich verstehe das Bestreben, Neulingen möglichst einfache Beispiele zu zeigen, aber so etwas führt schnell zu schlechten Angewohnheiten. Es ist meines Erachtens besser, lieber gleich den korrekten Weg zu wählen.
 
Zurück
Oben