C malloc, free und ein Array - Verständnisproblem

SparkMonkay

Commander
Registriert
Feb. 2013
Beiträge
2.337
Moinsen,

nachdem ich länger mit Java unterwegs war darf ich wieder C Programmieren. Jetzt will ich auch mal wieder in C rein kommen und dachte mir:"Programmierste mal was schönes."
Ein Programm welches Primzahlen "findet" erschien mir als richtig.

Code:
#include <stdio.h>
#include <stdlib.h>

int main()
{
	
	/***************************************************************************
	 *@pCounter 	Zähler für die Anzahl meiner Primzahlen(u.A. größe des Array's)
	 *@startelement Das erste Element bzw die erste Primzahl
	 *@end 			Bis wohin soll das ganze gehen?
	 ***************************************************************************/ 
	int pCounter=1;		
	int startelement=2;
	int	end;			

	/*****************************************************************************
	 *@primes 		Haupt-Array wo meine Zahlen drinnen sind
	 *@primesBackup	Backup-Array, wenn es gemalloct und freet werden soll, soll
	 * 				hierrüber die Elemente dann in den "neuen" Haupt-Array kopieren
	 *****************************************************************************/
	int **primes[1];		
	int **primesBackup[1];	

	*primes[0]		=&startelement;		
	*primesBackup[0]=&startelement;	

	printf("Bis zu welcher Zahl die Primzahlen ausgeben?");
	scanf("%d\n", &end);

	

	printf("The first prime ist %d\n",**primes[0] );
	primes=malloc(sizeof(int *));
	if(primes==NULL) 
	{
		printf("primes  couldn't been malloced ERROR");
		return 1;
	}
	primes[0]=malloc(sizeof(int));
	if(primes[1]==NULL)
	{
		printf("primes at X couldn't been malloced ERROR");
		return 1;

	}
	free(primes);
	free(primes[0]);
	
	return 0;
}

Wie habe ich es mir gedacht:
Also: Ein Nutzer gibt eine Zahl ein, die z.B. größer gleich 2 ist.
Dann weise ich der Variable end diesen Wert zu.
dann sollte eine for-Schleife kommen, mit der ich das bis end durchlaufe.

Ich habe ein Array oben, mit dem was ich mir aus dem netten Internet rausgelesen habe, habe ich es jetzt soweit hinbekommen. Der Plan ist: Wenn eine Primzahl gefunden wurde dann soll das Array primes[ ] gemalloct und freet werden, die innreren Array-Elemente ebenfalls. Dann setze ich den Array-Counter um einen höher, dann erstelle ich "int **primes[2]", denn pCounter ist dann auf 2. Ich kopiere dann meine Werte aus "primesBackup" zu "primes" und an die letzte Stelle kommt dann meine Primzahl hin.
Was ist mein Fehlercode:
Code:
primes.c: In function ‘main’:
primes.c:33:8: error: incompatible types when assigning to type ‘int **[1]’ from type ‘void *’
  primes=malloc(sizeof(int *));
        ^

Habe ich jetzt malloc und free falsch verstanden? Denn so wie ich es verstehe nehmen die das was ich will sozusagen aus dem Speicher raus.

MfG Spark
 
Code:
	printf("The first prime ist %d\n",**primes[0] );
Hier hast Du eine Indirektion '*' zu viel drin.

Code:
	primes=malloc(sizeof(int *));

das geht nicht, da primes kein Zeiger sondern eine Array-Konstante ist.

usw.

Ich denke, bevor Du mit so übermäßig komplizierten Konstrukten anfängst, solltest Du nochmal die Grundlagen auffrischen. Ich denke, Du hast keine klare Vorstellung von Zeigern, Arrays von Zeigern etc. Damit solltest Du dann anfangen.
 
Wenn du mit malloc() Speicher belegst, musst du den Rückgabewert bei de Zuweisung casten, z. B.:
Code:
int *zahlen;
zahlen = (int*)malloc(sizeof(int) * 10);

für eine Liste von 10 ints. Ohne den Typecast (int*) bekommst du einen Fehler wie den, den du gepostet hast.

Im übrigen verstehe ich aber auch den Typen von primes nicht:

int - eine Zahl
int* - eine Liste von Zahlen <- das ist es doch, was du willst, oder?
int** - eine Liste von Listen von Zahlen
int**[1] - eine Liste, die ein Element hat, das eine Liste von Listen von Zahlen ist <- das hast du

Obendrein sind deine free-Anweisungen in der falschen Reihenfolge. Nachdem free(primes) ausgeführt wurde, ist free(primes[0]) keine gute Idee mehr. Wenn du verschachtelte Strukturen freigeben willst, immer von innen nach außen.
 
Zuletzt bearbeitet:
Gut dann würde ich mal sagen ich arbeite mich erstmals von 0 hoch.
Werde mich dann mal an C-how-to.de wenden.
 
NullPointer schrieb:
Im übrigen verstehe ich aber auch den Typen von primes nicht:

int - eine Zahl
int* - eine Liste von Zahlen <- das ist es doch, was du willst, oder?
int** - eine Liste von Listen von Zahlen
int**[1] - eine Liste, die ein Element hat, das eine Liste von Listen von Zahlen ist <- das hast du

int* - ein Zeiger (eine Adressvariable) auf int
int** - ein Zeiger auf int*, also auf einen Zeiger auf int
int**[1] - ein Array mit einem Element, in dem ein int** steht
 
SparkMonkay schrieb:
Gut dann würde ich mal sagen ich arbeite mich erstmals von 0 hoch.
Code:
#include <stdio.h>
#include <stdlib.h>

 int main()
{
 char buffer[512];
 int pCounter = 1;
 int startelement = 2;
 int end;
 int *primes;

 printf("Bis zu welcher Zahl die Primzahlen ausgeben?");
 fgets(buffer, sizeof(buffer), stdin);
 sscanf(buffer, "%d", &end);

 primes = malloc(end * sizeof(int));
 for (int i = startelement; i < end; i++) {
    primes[i] = 1;
 }

 for (int i = startelement; i < end; i++) {
    if (primes[i]) {
       for (int j=i; i*j<end; j++) {
          primes[i*j] = 0;
       }
    }
 }

 for (int i = startelement; i < end; i++) {
    if (primes[i]) {
       printf("%d. Primzahl = %d\n", pCounter++, i);
    }
 }

 free(primes);
 return 0;
}
 
asdfman schrieb:
Nein, muss er nicht.

Und sollte er auch nicht.

http://stackoverflow.com/questions/...-dangerous-about-casting-the-result-of-malloc

You won't get a compiler error, but a compiler warning. As the sources you cite say (especially the first one), you can get an unpredictable runtime error when using the cast without including stdlib.h.

So the error on your side is not the cast, but forgetting to include stdlib.h. Compilers may assume that malloc is a function returning int, therefore converting the void* pointer actually returned by malloc to int and then to your your pointer type due to the explicit cast. On some platforms, int and pointers may take up different numbers of bytes, so the type conversions may lead to data corruption.
 
Hoppla, wieder was gelernt. Ich war fest der Ansicht, eine Zuweisung ohne Cast würde in einem Compilerfehler enden.

@blöderidiot: Schon klar, aber wenn du in C Arrays bzw. Listen benutzen willst, dann ist z.B. int* der Typ der Wahl für eine Liste von ints. Der OP schien mir darüber nicht klar zu sein.
 
Ich war fest der Ansicht, eine Zuweisung ohne Cast würde in einem Compilerfehler enden.
Das ist in C++ auch so. Insofern ist deine Ansicht nicht ganz falsch, nur eben für eine andere Sprache.

int**[1] - eine Liste, die ein Element hat, das eine Liste von Listen von Zahlen ist <- das hast du
Und um das auch nochmal für den TE zu präzisieren, der Typ davon entspricht int***.

Beim Dereferenzieren gilt auch
Code:
int* a;
*a     ist äquivalent zu a[0] (Typ: int)
*(a+i) ist äquivalent zu a[i] (Typ: int)
 
Zuletzt bearbeitet:
Zurück
Oben