Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Probleme mit Arrays (Zeiger)

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
10.06.2005, 22:37 Uhr
Lensflare



hallo

also ich hab mir die FAQ hier über malloc durchgelesen und ich glaube es verstanden zu haben, aber bei meien testcode kommen dennoch unerwartete sachen:


C++:
  int *intArray;

  intArray = (int*)malloc(sizeof(int)*10);
  intArray[9] = 9;

  printf("intArray[9]: %i\n",intArray[9]);
  printf("Anzahl Slots: %i\n", sizeof(intArray)/sizeof(int));


Wieso kommt bei "Anzahl Slots" eine 1 raus und nicht 10, wie erwartet?
Mir ist klar, dass das array ein zeiger ist, aber ich verstehe es trotzdem nicht, weil ich doch mit malloc 10*int bytes für das array reserviere.


C++:
  int *intArray;
  
  intArray = (int*)malloc(sizeof(int)*10);

  intArray[9] = 9;
  printf("intArray[9]: %i\n",intArray[9]);

  intArray[17] = 17;
  printf("intArray[17]: %i\n",intArray[17]);



Hier scheint das programm garnichts dagegen zu haben, dass ich ausserhalb des angeforderten speichers schreibe und lese, es kommt auch noch wirklich 17 raus

dann ist noch diese komische sache:

C++:
  //Nachtrag:
  int *intArray = (int*)malloc(sizeof(int)*10);
  free(intArray);
  
  int *buffer = (int*)malloc(sizeof(int)*10);
  
  free(intArray);
  free(buffer);
  //Nachtrag Ende


  int *testArray;
  int *testArray2;

  testArray = (int*)malloc(sizeof(int)*10);
  testArray[5] = 1;
  
  testArray2 = (int*)malloc(sizeof(int)*10);
  testArray2[5] = 2;
  
  printf("%i\n",testArray[5]); //Anmerkung: testArray[5], nicht testArray2[5]


wieso wird der wert 2 aus dem testArray2 ausgegeben, statt dem wert 1 aus testArray ???
es scheint so, als würde testArray2 einfach den speicherblock von testArray bekommen, statt einen anderen... aber wieso?

EDIT: jedoch nur wenn vorher das kommt, was ich mit "//Nachtrag" markiert habe
--
Wenn das Gehirn so einfach wäre, dass wir es verstehen könnten, wären wir so einfach, dass wir es nicht verstehen könnten.
(Emerson Pugh Trost)

Dieser Post wurde am 10.06.2005 um 23:01 Uhr von Lensflare editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
10.06.2005, 22:48 Uhr
Pler
Einer von Vielen
(Operator)



C++:
sizeof(intArray)


ist nicht 10 oder 10*32 oder so, sondern Größe eines Zeigers auf ein int

Beim Schreiben gibts glaub ich öfter keine Probleme, aber beim Freigeben dann schon, aber dass machst du ja nicht.
Grundsätzlich kannst du hinschreiben, wo du willst, solange der Speicher noch zu deinem Prozess gehört ( denke so )


C++:
free(intArray);



Das dritte kann ich mir auch nicht vorstellen.

Dieser Post wurde am 10.06.2005 um 22:48 Uhr von Pler editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
10.06.2005, 22:59 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Pler jo solang du nicht über den für dein programm zugesicherten speicher schreibst, ists egal. du killst dir halt dein programm normalerweise, da du normalerweise dann den programmpointer usw mit überschreibst. Im debugger kriegste dann normalerweise "stack around '...' was corrupted" bzw heap, je nachdem wos liegt
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
10.06.2005, 23:04 Uhr
Pler
Einer von Vielen
(Operator)


das probier ich aus!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
10.06.2005, 23:09 Uhr
Pler
Einer von Vielen
(Operator)


Also dieses Programm funktioniert super, egal wie lang die eingegebene Zeichenkette ist.


C++:
#include <stdio.h>

int main( )
{
        char* szVar;

        szVar = malloc( 5 );

        gets( szVar );

        printf( "%s" , szVar );


        free( szVar );

        return 0;
}

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
10.06.2005, 23:13 Uhr
Lensflare



ich hab gedacht, dass ein zeiger auch die information enthält, wie gross der block ist, auf den er zeigt... aber ok, anscheinend ist es nicht so

also demnach ändert sich mit free() nichts am zeiger selbst, sondern der speicherblock wird einfach freigegeben und bei der nächsten speicheranforderung wird also wieder auf den freigegebenen platz reserviert, richtig?

dann müsste auch daruas folgen, dass der zeiger durch malloc() auf eine andere stelle im speicher zeigen muss, wenn die vorherige schon belegt ist.
--
Wenn das Gehirn so einfach wäre, dass wir es verstehen könnten, wären wir so einfach, dass wir es nicht verstehen könnten.
(Emerson Pugh Trost)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
10.06.2005, 23:23 Uhr
~CDW
Gast



Zitat:
Wieso kommt bei "Anzahl Slots" eine 1 raus und nicht 10, wie erwartet?

weil sizeof(Zeiger) die Zeigergröße zurückliefert - diese ist auf einem >286 und einem 32-Bit OS normalerweise 32-Bit bzw 4 Byte. Int ist (gewönlich - je nach Compiler variiert das aber) 4 Byte. Also hat man 4 durch 4 =1 .


Zitat:
Hier scheint das programm garnichts dagegen zu haben, dass ich ausserhalb des angeforderten speichers schreibe und lese, es kommt auch noch wirklich 17 raus

pures Glück. Wenn Du noch mehr in die Funktion reinmachst oder weitere funktionen tätigst (die auch auf Speicher zugreifen) garantiert Dir niemand dass der Wert nicht überschrieben wird, da der Speicher "intern" als frei markiert ist und deshalb "zum abschuss freigegeben".
Hm, gibts denn nicht eine Option a la "Arraygrenzen prüfen"?


Zitat:
wieso wird der wert 2 aus dem testArray2 ausgegeben, statt dem wert 1 aus testArray ???

wegen dem free(buffer) - denn das ist "zuviel" (Du hast ja kein malloc für diesen free). Daher:
meine lcc32 hilfe sagt dazu:

Zitat:
Otherwise, if the argument does not match a pointer earlier returned by the calloc, malloc,or realloc function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.

was ich mir vorstelle: intern wird über mallocs (bzw. Speicherreservirung durch malloc) ein "buch" geführt - dazu gehört auch ein "Zähler". Bei jedem malloc wird er incrementiert, bei free decrementiert. so dass der in Deinem fall bei dem free zuviel sich "verzählt".
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
10.06.2005, 23:24 Uhr
Pler
Einer von Vielen
(Operator)



Zitat:

also demnach ändert sich mit free() nichts am zeiger selbst, sondern der speicherblock wird einfach freigegeben und bei der nächsten speicheranforderung wird also wieder auf den freigegebenen platz reserviert, richtig?



Muss nicht auf den gleichen Platz sein.
Aber der Inhalt des Speichers wird beim free() nicht gelöscht oder überschrieben. Nur freigegeben.
Ich weis aber nicht, warum man dann manchmal nicht mehr auf die alten Daten zugreifen kann, obwohl sie ja noch im Speicher sind ( manchmal gehts ). Bevor ich hier wieder Mist erzähle, warten wir mal lieber, was FloSoft dazu sagt.



Zitat:

dann müsste auch daruas folgen, dass der zeiger durch malloc() auf eine andere stelle im speicher zeigen muss, wenn die vorherige schon belegt ist.



Wie meinst du dass?
Malloc gibt dir eben einen Zeiger, hinter dem der von dir angeforderte Speicher steht. Dieser Speicher war vorher sicherlich noch nicht belegt.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
10.06.2005, 23:34 Uhr
~CDW
Gast


wie kommen denn die vielen Beiträge dahin, als ich das verfasst hab waren die noch nicht da *mich wunder *
also man kann versuchen ein paar malloc-umsetzungen per google zu finden. Da speicherreservierung die Sache des OS ist muss die malloc funktion daher OS-spezifischer vorgehen. Imho setzen dabei viele Lösung sich so zusammen dass ein Bereich schon mal reserviert und verwaltet wird - malloc "zwankt" sich immer was davon ab. Dabei kommt eine Liste zum einsatz wo auch eben ein "zähler" drin ist - der per malloc/free incrementiert/decrementiert wird. Da aber das wirklch nur eine umsetzungfrage ist und das Verhalten ja nicht definiert ist könnte es durchaus sein dass andere compiler hier so übersetzen dass eine 1 ausgegeben wird.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
10.06.2005, 23:38 Uhr
Lensflare



Wenn ich 4 char arrays erstelle, mit jeweils 4 "slots"

C++:
  
  char *array1 = (char*)malloc(4);
  char *array2 = (char*)malloc(4);
  char *array3 = (char*)malloc(4);
  char *array4 = (char*)malloc(4);


dann hab ich ja 4x4 bytes reserviert: (X = reserviertes byte, O = freies byte)

Code:
  
  XXXX XXXX XXXX XXXX


und wenn ich das erste und das dritte array freigebe, dann hab ich zwei "Lücken" drin:

Code:
  
  OOOO XXXX OOOO XXXX


wenn ich jetzt aber ganz viele solcher lücken habe, dann hab ich doch eigentlich viel freien speicher, kann aber dennoch kein array reinquetschen, das grösser ist, als 4 bytes. Wie wird das problem gelöst? werden die daten automatisch verschoben und die adressen in den zeigern verändert?
--
Wenn das Gehirn so einfach wäre, dass wir es verstehen könnten, wären wir so einfach, dass wir es nicht verstehen könnten.
(Emerson Pugh Trost)

Dieser Post wurde am 10.06.2005 um 23:42 Uhr von Lensflare editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: