C Frage zu Int-arrays und speicher-allokierung

Status
Für weitere Antworten geschlossen.

elektro2

Cadet 4th Year
Registriert
Feb. 2014
Beiträge
67
Hallo liebes Forum. Ich habe eine Frage :

Hiermit erstelle ich ja so gesehen ein dynamisches Array, dass folglich behandelt werden kann :

Code:
char *s=(char *) malloc(20*sizeof(char));

s="Hallo";

printf("%c", s[2]);
printf("%s", s);

Wie mach ich das gleiche, wenn ich z.b diese Form habe:

Code:
int *p=(int *)malloc(20*sizeof(int));

// führt nicht zum Ergebnis

p={1,3,4,5,6}

printf("%d", p[2]);   // SOllte jetzt 4 sein !!! // Programm fehlerhaft

Habt ihr eine Idee, worin mein Fehler liegt oder die komplette Grundüberlegung?

Danke im Voraus !!!!
 
Semikolon hinter p={1,3,4,5,6} vergessen.
 
Also bei mir (VC 2012) kompiliert der Compiler dein Beispiel gar nicht:

Folgendes tut:

Code:
#include <stdlib.h>

int _tmain(int argc, _TCHAR* argv[]) {
  int *p = (int*) malloc(5*sizeof(int));
 
  //p = {1,2,3,4,5}; <-- kompiliert nicht!!
  
  p[0] = 1;
  p[1] = 2;
  p[2] = 3;
  p[3] = 4;
  p[4] = 5;
 
  printf("%d\n", p[2]);
 
  free(p);
  
  return 0;
}


Greetz
hroessler
 
führt leider auch mit semikolon zu einem Fehler ... " Expected Expression "
Ergänzung ()

So klappts.. aber kann man das nicht direkt deklarieren? also p= .....???
 
Versuch es bitte mal mit
p[] = {1,2,3,4,5};

Laut Handbuch soll das klappen. Kann es leider nicht selber testen, aktuell kein C-Compiler vorhanden.
 
Der Unterschied ist, dass dein erstes Beispiel eine Zuweisung ist, das zweite aber eine Initialisierung. Letztere kannst/darfst du nur bei der Deklaration machen, danach aber nicht mehr. Nachträglich wäre illegal und sollte von keinem Compiler akzeptiert werden.
 
elektro2 schrieb:
Hallo liebes Forum. Ich habe eine Frage :

Hiermit erstelle ich ja so gesehen ein dynamisches Array, dass folglich behandelt werden kann :

Code:
char *s=(char *) malloc(20*sizeof(char));

s="Hallo";

printf("%c", s[2]);
printf("%s", s);

Zeile 3 ist schon mal eine sauschlechte Idee. Nachdem malloc() dir die Startadresse des eben allozierten Speicherblockes gegeben hat und du diese in der Zeigervariablen s gespeichert hast, überschreibst du diese prompt mit der Anfangsadresse des String-Literals "Hallo" (in C sind String-Literale konstante Speicherblöcke). Damit ist der dynamisch allozierte Speicherblock für dich nun nicht mehr erreichbar ... da hast in nur 3 Zeilen ein wunderschönes Speicherleck programmiert. ;)
Obendrein hast du noch fälschlicherweise die Adresse des String-Literals "Hallo" (was eigentlich vom Typ const char* ist) in einer Variablen des Types char* (also nicht const) gespeichert. Hat dein Compiler dir da keine Warnungen angezeigt??
Ergänzung ()

P.S. Wenn du wirklich was in den von dir allozierten Speicherblock schreiben möchtest, tue dies mit strncp().

Code:
size_t NUM_OF_CHARS = 20;
char *s= malloc(NUM_OF_CHARS); /* Der Rückgabewert von malloc() sollte übrigens __nicht__ gecastet werden. Und den * sizeof(char) Käse kannst du dir auch sparen, weil sizeof(char) per Definition immer 1 ist. */

strncpy( s, "Hallo", NUM_OF_CHARS - 1 ); /* -1 weil die terminierende Null auch noch in den Puffer passen muß. */
 
Zuletzt bearbeitet:
Man kann einen String-Literal keiner Variablen zuweisen. Das geht einmal bei der Initialisierung (da wird der Zeiger auf den Datenbereich des Images im Speicher gelegt), was keine richtige Zuweisung ist und danach nie wieder. Wie bereits genannt ist strncpy() hier das Mittel der Wahl.

Ein dynamisch allokiertes int-Array zu füllen kann man auf verschiedene Weisen machen, aber auch nicht mit einem Array-Literal, wie OP es versucht und damit schon gescheitert ist. memcpy() oder ggf. memset() sind z.B. zwei von vielen Möglichkeiten.
 
Um antred's und asdfman's Punkte noch ein bisschen zu veranschaulichen, nimm mal diesen Code:
Code:
#include <stdio.h>
#include <stdlib.h>

int main()
{
	char* szText = malloc( 20 );

	printf( "Pointer ...: %p\n", &szText );
	printf( "Points to .: %p\n", szText );

	strncpy( szText, "Hello World!", 19 );

	printf( "\nPointer ...: %p\n", &szText );
	printf( "Points to .: %p\n", szText );
	printf( "Value .....: %s\n", szText );

	szText = "Goodbye World!";

	printf( "\nPointer ...: %p\n", &szText );
	printf( "Points to .: %p\n", szText );
	printf( "Value .....: %s\n", szText );

	return 0;
}

Mit dieser Augabe:
Code:
Pointer ...: 0100FD58
Points to .: 01207CA0

Pointer ...: 0100FD58
Points to .: 01207CA0
Value .....: Hello World!

Pointer ...: 0100FD58
Points to .: 00302074
Value .....: Goodbye World!

Wie du unschwer erkennen kannst hat Zeile 17 deinen Zeiger ( szText ) verändert und zeigt nun auf eine ganz andere Adresse. Wenn du mit malloc Speicher alloziierst, dann musst du diesen auch wieder freigeben, das kannst du aber ab Zeile 17 nicht mehr, weil du nicht mehr weißt wo dein Speicher ist, den dir malloc gegeben hat. Deshalb Memory Leak und du kannst nichts mehr an die Adresse schreiben, auf die szText zeigt, weil es eben ein String-Literal vom Typ const char* ist und es sich deshalb um Read Only Memory handelt und je nach Compiler und OS kann dir das Programm mit Page Fault oder Access Violation abschmieren, falls du es trotzdem versuchen solltest.

Gruß
BlackMark
 
Status
Für weitere Antworten geschlossen.
Zurück
Oben