Schreibgeschützter String manchmal beschreibbar, manchmal nicht?



  • Hallo

    An dieser Stelle (also an der Stelle wo ich ein Zeichen dem anderen zuweise, die if Abfrage und Positionierung des Cursors klappt einwandfrei, und auch die Positionen in der Zeichenkette sind laut Debugger die richtigen) bekomme ich von meinem Compiler immer eine Zugriffsverletzungsfehler beim Schreiben/Lesen auf Adresse...

    if(w>0)
    	{
    		gotoxy(0, 18);
    		switch (w)
    		{
    	    case 1: cout << a[z-1].name;
    			punktx = strlen(a[z-1].name);
    			cursor(punktx, b);  
    			do{ 
    			if (b == 8) // bei Backspace
    			{
    			i = punktx-1; //neuinitalisierung zählvariable
    			while(a[z-1].name[i] != '/0')
    			{
    			a[z-1].name[i] = a[z-1].name[i+1];
    			i=i++; 
    			}
    			cout << a[z-1].name;
    			}
    		    else
    			{
    			a[z-1].name[punktx] = b;
    			cout << a[z-1].name[punktx];
    			punktx = punktx + 1;
    			}  
    			cursor(punktx, b);
    			}while(b!=13);
    		    break;
    		case 2:
    ...
    

    Jetzt hab ich herausgefunden dass es sowas wie schreibgeschützte Zeichenketten gibt, und da mein Array über ein struct deklariert wird denke ich mal dass es eine ist.

    struct datum
    {
    	char tag[3], monat[11], jahr[5];
    };
    struct t_adress
    {
    	char name[30], vorname[30], strasse[100], ort[100], hnr[10], plz[10];
    	char flag;
    	datum date;
    };
    
    ....
    
    void main()
    {
    	int auswahl=0, out=0, zsort=0;
    	int zm = 6; //Menüeinträge
    	t_adress adressen[10];
    
    	do{
    		switch (auswahl)
    		{
    		 ....
    		case 4: edit(adressen);
    			auswahl=zm+1;
    			break;
    		case 5: sort(adressen, zsort);
    			auswahl=zm+1;
    			break;
                     ....
    

    alles schön und gut, und dann muss ich mir eben was überlegen wie ich das Problem löse, ABER, in einer anderen Funktion sortiere ich das Array, und da kann ich die strings Problemlos überschreiben.

    t_adress temp[1];
    	int i, j;
    
    	if(zsort == 41)
    	{
    		for (i=0;i<ds;i++)
    		{
    			for(j=1;j<ds;j++)
    			{
    				if ( a[j-1].name[0] > a[j].name[0])
    				{
    					temp[0] = a[j];
    					a[j] = a[j-1];
    					a[j-1] = temp[0];
    				}
    			}
    		}
    	}
    

    Mich würde mal interessiern wieso das so ist, oder ob das vielleicht gar keine schreibgeschützten strings sind und ich irgendwas falsch mache.

    Es sind ca. 400+ Zeilen Code, die wollte ich jetzt nicht komplett hier posten, aber wenn euch was zum verständnis fehlt (oder mein code zu verwirrend aussieht 😃 fragt ruhig) 🙂

    Danke schonmal 🙂



  • Du greifst vermutlich an irgendeiner Stelle auf eine ungültige Arrayposition zu.

    Da du statt C++ mit std::string, std::vector oder auch selbst geschriebenen Klassen lieber reines C benutzt, ist das vermeiden oder entdecken des Fehler natürlich nicht ganz einfach.

    Und 400 Zeilen durchsuche ich dir sicher nicht nach dem Fehler 😉

    Lars



  • Was wir benutzen ist leider vorgeschrieben vom Lehrer in der Berufsschule... sonst sähe dass alles ganz anders aus 🙂

    Ich hab aber eigentlich mit dem Debugger geprüft auf welche Stelle er zugreift, das sah alles relativ richtig aus...

    z.B. beim string "Teest" sah der Ausdruck im Debugger ungefähr so aus
    "..[2] = ..[3]" ... dass die Abfrage mit dem '/0' vielleicht probleme macht hab ich auch schon probiert und ihn wirklich nur mal 3 in 2 schreiben lassen, macht er aber auch nicht..

    Den Fehler such ich gerne selbst, hätte nur gerne gewusst ob das wirklich an so nem "schreibgeschützten" array liegen kann oder eben an was anderem



  • Kaum fragt man irgendwo nach löst sich das Problem fast von alleine... *schäm*

    if (b == 8) // bei Backspace
    			{
    			i = punktx-1; //Neuinitialisierung Zählvariable
    			do
    			{
    			a[z-1].name[i] = a[z-1].name[i+1];
    			i=i++; 
    			}while(i < strlen(a[z-1].name));
    			gotoxy(0,18);
    			cout << a[z-1].name;
    			}
    

    so klappts, sieht nach falscher Schleife und falscher Bedingung aus 😞



  • Bei so kurzen Quelltextabschnitten kann man Dir nur schwer helfen.

    Fragen:
    Welchen Typ und Wert haben die Variablen w und z?

    Nur so auf den ersten Blick ist in diesem Programm einiges nicht in Ordnung:
    In Zeile 16: i=i++;
    Das ist doppelt gemoppelt, i++ ist schon was du hier brauchst.

    In Zeile 13 fragst Du nach dem Stringende bei i nach, greifst jedoch
    auf die Position i+1 in Zeile 15 zu.

    Was passiert wenn punktx NULL wird?

    Zeile 14 void main()
    sollte immer zumindest ein int zurück liefern.

    Die Benutzung von char[] ist nicht zu empfehlen, da der Speicherbereich fix ist.
    Nur wenn die Zeichenketten außerhalb der Main-Funktion vereinbart wurden, sind die Variablen
    automatisch mit NULL vorbelegt. Benutzt du diesen Ansatz in Funktionen, so ist der Inhalt
    undefiniert und es muss erst manuell auf Null gesetzt werden.

    "Jetzt hab ich herausgefunden dass es sowas wie schreibgeschützte Zeichenketten gibt, und da mein Array über ein struct deklariert wird denke ich mal dass es eine ist."

    Da sehe ich nichts von const.
    Die Zeichenketten sind nicht schreibgeschützt.

    Ein Lösungsansatz ist überall wo du Probleme hast ein printf einzufügen und alle Werte und Positionen anschauen. Dann sollte das Problem(e) schnell gelöst sein.



  • Vielen dank schonmal 🙂

    w und z sind beide vom Typ int und haben zumindest bei meinen Test beide den Wert 1, da über w im Switch geprüft wird ob der Benutzer z.B. mit 1 das Element "name", mit 2 "vorname" etc... bearbeiten will, ist w=0 will der Benutzer nichts bearbeiten.
    Über z wird der jeweilige komplette Datensatz angesteuert, also hier mit 0 die erste Zeile/das erste Element..

    Danke für die Hinweise mit i++ und int main... das mit dem Stringende hab ich irgendwie nie so ganz verstanden, deswegen war da auch der Wurm drin mit dem /0.
    Das ichs jetzt mit strlen() mache (mitlerweile mit strlen()+1 weils irgendwie nur so funktioniert), ist wohl auch nicht die optimalste Lösung denke ich.

    char[] wurde uns so vorgegeben... aber für mein Verständnis, was heißt denn außerhalb der main funktion? nur wenn ich es als const deklariere?

    Und Zeichenketten sind dann also auch nur schreibgeschützt wenn als const deklariert?

    EDIT:
    Achja, und wenn punktx NULL ist das muss ich noch abfangen denk ich.

    Bin da bei allem noch ziemlich unsicher, lerne zwar schon seit 2 Jahren c und c++ grundlagen, aber hab jetzt in der Berufsschule neu angefangen, und das Programm ist eine Langzeitaufgabe das abgeändert, verbessert und erweitert werden soll je mehr wir über die drei Jahre (jetzt noch 2) dazu lernen...



  • "...was heißt denn außerhalb der main funktion?"
    Dafür schau dir mal das kleine Programm hier an!

    #include <stdio.h>
    int *ptr;
    int i;
    
    // <COMPILE>g++ -o nullsetzten nullsetzten.cpp</COMPILE>
    
    void fnk(void) {
      int *ptr;
      int i;
      printf("fnk:\n");
      printf(" pointer: %x\n", ptr);
      printf("     int: %i\n", i);
    }
    
    int main(int argc, char **argv) {
      printf("global:\n");
      printf(" pointer: %x\n", ptr);
      printf("     int: %i\n\n", i);
      printf("fnk:\n");
      fnk();
      return 0;
    }
    

    ... nur wenn ich es als const deklariere?
    Ja genau. Nur Variablen die mit const=Konstante vereinbart wurden.

    Gruß
    trooper


Log in to reply