Pointer .. aber so?

Message
Author
chrisjumper
Posts: 104
Joined: 12. Feb 2004 12:53
Location: Jülich

Pointer .. aber so?

#1 Post by chrisjumper »

Hallo zusammen!

Ich hab da wieder mal eine Frage. Also in so einem Sourcecode, für ein Beispielprog. findet sich die Zeile:

...
if ((buffer = shmat(shmem_id, 0, 0)) == (char *)-1)
...

Leider wird dies in dem Buch nicht genauer erklärt.. :(

die Variable "buffer" ist übrigens eine Char-Pointer-Variable.

Was mich verwundert ist dieses "(char *)" in Klammern.
Man kann also mitten im Sourcecode eine neue Pointer Variable deklarieren.. !?! Doch.. hier fehlte dann gänzlich die bezeichnung der Variablen.. "-1" kann doch keine Bezeichnung sein... oder?

Auf die Variable "buffer".. kann es sich doch auch nicht beziehen da diese jehnseits von dem "==" steht... es verwirrt mich doch sehr.

Oder wird her die Pointer-Speicheradresse umd den Wert eines "Handelsüblichen ;)" Charspeicherblocks Dekrementiert?

LG Chris

Guest

#2 Post by Guest »

Funktioniert das Beispiel in dem Buch? Sieht eher wie ein (Druck)fehler aus.

chrisjumper
Posts: 104
Joined: 12. Feb 2004 12:53
Location: Jülich

es funktioniert

#3 Post by chrisjumper »

Lieber Gast,

also wie soll ich das sagen.. es Funktioniert einwandfrei :)

und wenn ich das "(char *)" rauslösche... kommt beim kompilieren sofort die Fehlermeldung:

....
sharedmem2.c: In function `main':
sharedmem2.c:21: warning: comparison between pointer and integer
....

von daher denke ich mittlerweile das das sternchen dahingehört.. damit er den Wert vergleichen kann der unter der Speicheradresse von buffer zu finden ist... aber... dazu steht das "(char *)" doch auf der falschen Seite und ein einfaches sternchen hätte es doch auch getan oder.. ich probiers jetzt nochmal..

LG Chris

chrisjumper
Posts: 104
Joined: 12. Feb 2004 12:53
Location: Jülich

ach nee bin ich... tsk...

#4 Post by chrisjumper »

So mir ist grade aufgefallen..

das es sich hier ja um die "Fehlermeldung" handelt wenn die Funktion "shmat()" keinen speichersplatz reservieren kann.. und sie den wert -1 zurück gibt.. so kann es dann doch sein das das Programm nicht ordentlich laufen würde.. wenn shmat fehlschlägt...

ich hab jetzt auch die Funktion abgeändert und zwar so:

....
if ( *(buffer = shmat(shmem_id, 0, 0)) == -1 )
{
perror("sharedmem: shmat() failed");
shmctl(shmem_id, IPC_RMID, 0);
return(1);
}
......

und das Kompilieren funktioniert einwandfrei..

ich versuch jetzt einfach mal den speicher von buffer mit dem Wert -1 zu füttern und dann schau ich mir mal an wie die fehlermeldung reagiert.

chrisjumper
Posts: 104
Joined: 12. Feb 2004 12:53
Location: Jülich

OH tut mir leid!

#5 Post by chrisjumper »

Also.. mir ist das schon fast peinlich..

ich hab das jetzt ausprobiert und mein lieber gast hatte recht!

So wie es im Buche stand funktionierte es nicht.

Es tut mir leid das ich eure Forum jetzt quasi mit "Tagebucheinträgen" meines Abends füllte.

.........

Lieber Administrator,
diese ganze Thrad kann durchaus gelöscht werden!

Ich versichere auch ab sofort mehr selbst auszuprobieren, bevor ich hier poste!

c-coder

#6 Post by c-coder »

also erst mal werd nicht gleich paranoid wegen dem administrator. ich denke so wie es im buch stand soll es auch sein denn die funktion shmat wird darauf überprüft ob sie stat nem gültigen char zeiger eine -1 ausgibt. dabei wird das (char*) lediglich vorangestellt damit der compiler es zulässt den char * rückgabewert mit -1 zu vergleichen. wenn du es in '*(buffer = shmat(shid,0,0)) == -1' änderst machst du dein programm kaputt denn dann wird es versuchen den ersten char aus dem pointer mit -1 zu vergleichen was aber nicht sinn der sache ist sondern es soll ja der zeiger mit -1 verglichen werden um dann entsprechend zu handeln. außerdem ist diese änderung auch gefährlich weil der zeiger null sein könnte und/oder in einen ungültigen bereich verweißt was zu einem zugriffsfehler führen kann und dein programm abstürzt oder gar dein system killt.

chrisjumper
Posts: 104
Joined: 12. Feb 2004 12:53
Location: Jülich

Also nein.. nein mein System mach ich so ncht kaputt :)

#7 Post by chrisjumper »

Nabend c-coder,

bei der Variablen "buffer" handelt es sich um einen Char-Pointer-Varriable, die "nur" Adressen speichert.

Da ich aber ihren Inhalt mit dem Wert "-1" vergleichen will, muss ich das Sternchen davorsetzen.. damit er auf den Inhalt des Pointers zeigt. Ohne Sternchen vergleicht er ja die Speicheradresse mit -1.

In dem Buch steht das aber eindeutig auf der falschen Seite des vergleiches.

Hiermit

if ( *(buffer = shmat(shmem_id, 0, 0)) == -1 )

überprüft er (nachdem er die Funktion "shmat" ausgeführte und an den Zeiger-Variable "buffer" übergeben hat) ob dieser Wert der sich dort im Speicher befindet genau -1 entspricht.

Getestet habe ich es indem ich der Variablen "buffer"... den Wert -1 übertrug.

Das "Orginalprogram", so wies im Buche steht.. lief nicht wie erwartet. Wohl aber mit dem Sternchen auf der anderen Seite. Das es sie bei dieser Variablen um einen char-Pointer-Variable handelt weiß der Compiler auch noch, durch die Deklarierung am Anfang...

Das System zerhau ich mir dadurch auch nicht, weil hier vergleicht er ja in der If-Abfrage nur die beiden Zahlen und verändert sie nicht.

LG Chris

c-coder

#8 Post by c-coder »

nein mann du hast do gesagt:
die Variable "buffer" ist übrigens eine Char-Pointer-Variable.
das heißt buffer ist deklariert als: 'char *buffer'

wenn du

Code: Select all

*buffer
machst dann ist das gleich dem ersten char in buffer. kan nja sein das buffer vom typ 'char **buffer' ist aber das hast du nicht gesagt. jedenfalls wenn buffer ein char pointer istz dann entält es nur chars. wenn du willst das es zeiger enthält dann musst du es als char **buffer deklarieren aber ob das vom programm beabsichtigt ist wag ich zu bezweifeln. also ich bin sicher das du dich irrst. ansonsten poste mal die deklaration von shmat und buffer.

chrisjumper
Posts: 104
Joined: 12. Feb 2004 12:53
Location: Jülich

#9 Post by chrisjumper »

Hi c-coder,

schön das du auch so ein Nachtmensch bist :)
Also.. ich hab hier gleich mal den ganzen "Orginalcode" gepostet... so steht er im Buch. Der Titel des Buches leutet übrigens "C und Linux" von Martin Gräfe aus dem Hanser Verlag (2. Auflage).

Code: Select all

#include <stdio.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/wait.h>

int main&#40;&#41;
&#123;
	int shmem_id;
	char *buffer;
	
	if &#40; &#40;shmem_id = shmget&#40;IPC_PRIVATE, 80, SHM_R | SHM_W&#41;&#41; == -1&#41;
	&#123;
		perror&#40;"sharedmem&#58; shmget&#40;&#41; failed"&#41;;
		return&#40;1&#41;;
	&#125;
	
	if &#40; &#40;buffer = shmat&#40;shmem_id, 0, 0&#41;&#41; == &#40;char *&#41;-1 &#41;
	&#123;
		perror&#40;"sharedmem&#58; shmat&#40;&#41; failed"&#41;;
		shmctl&#40;shmem_id, IPC_RMID, 0&#41;;
		return&#40;1&#41;;
	&#125;
	
	buffer&#91;0&#93; = '\0'; 
	
	if &#40;fork&#40;&#41; == 0&#41;	
	&#123;
		sprintf&#40;buffer, "Message from child process"&#41;;
		shmdt&#40;buffer&#41;;
		return&#40;0&#41;;
	&#125;
			
	wait&#40;NULL&#41;;
	printf&#40;"Child process wrote into buffer&#58; '%s'\n", buffer&#41;;
	
	shmdt&#40;buffer&#41;;
	shmctl&#40;shmem_id, IPC_RMID, 0&#41;;
	return&#40;0&#41;;
&#125;
Die Sache mit den zwei Sternchen "**" besagt doch das der Pointer auf einen weiteren Pointer zeigt, der wiederum auf einen Wert zeigt.

Aber nun habe ich ewas über eine "Zeigerkonventierung" gelesen.. bei der man einen Pointer des Types int via (char *) in einen char Pointer umwandeln kann... ist dies hier vielleicht gemeint? So als "Achtung das ist ein Char Pointerm, nicht als Integralwerd lesen?" Hmm das macht aber doch keinen Sinn.. -1 ist doch eine Integer Wert oder nicht?

Gute Nacht C-Coder.. und danke das du mir hilfst!

Chris

Guest

#10 Post by Guest »

chrisjumper wrote: char *buffer;

...

if ( (buffer = shmat(shmem_id, 0, 0)) == (char *)-1 )
{
perror("sharedmem: shmat() failed");
shmctl(shmem_id, IPC_RMID, 0);
return(1);
}

buffer[0] = '\0';
[/code]

Die Sache mit den zwei Sternchen "**" besagt doch das der Pointer auf einen weiteren Pointer zeigt, der wiederum auf einen Wert zeigt.

Aber nun habe ich ewas über eine "Zeigerkonventierung" gelesen.. bei der man einen Pointer des Types int via (char *) in einen char Pointer umwandeln kann... ist dies hier vielleicht gemeint? So als "Achtung das ist ein Char Pointerm, nicht als Integralwerd lesen?" Hmm das macht aber doch keinen Sinn.. -1 ist doch eine Integer Wert oder nicht?

Gute Nacht C-Coder.. und danke das du mir hilfst!

Chris
ja ich mach heut die nacht durch weil ich morgen(bzw. später also heute :P) keine schule hab.
ja aus dem quelltext ist kein fehler zu erkennen. buffer ist ein zeiger auf char also ´wenn du den vergleich in *(buffer = shmat(...)) änderst machst du ein fehler. es soll nämlich überprüft werden ob die funktion shmat erfolgreich verläuft und einen zeiger ungleich -1 ausspuckt. ein zeiger ist nur eine speicheraddresse also abstrakt gesehen nur ein zahlenwert. daher kann mann ihn auch mit -1 vergleichen. worauf es zeigt ist letzlich egal und bleibt dem programmierer überlassen. ein zeiger vom typ 'char*' nach 'int*' zu konvertieren ist zwar möglich solltest du aber lassen denn die variablengröße zwischen char und int ist verschieden.
am besten ließt du nochmal genau die bedeutung von zeigern und den unterschied zu 'normalen' variablen nach, da dies für das verständnis dieses beispielcodes grundlegend bedeutsam ist.

blubb

#11 Post by blubb »

die variablengroesse von int und char ist verschieden, aber nicht von *char und *int ;)
sind beides 4byte, hat glaub ich was mit den alten 8086er zu tun als der speicher groesser wurd und alles auf 64kbyte segmente zeigen musst...

sollte was falsch sein, bitte um korrektur ,)

blubb

User avatar
bernd klein
Posts: 11
Joined: 13. May 2004 22:14
Location: Ritterhude

#12 Post by bernd klein »

Ich hab ne prima Buchempfehlung wenns ums Programmieren in UNIX-Umgebungen geht

Linux-Unix Systemprogrammierung

Da steht alles drin, auch Shared-Memory-programmierung.

Ach übrigens, ich hab im letzten Projekt ein Reihe von Klassen (C++) geschrieben die das ganze SharedMemory Gehampel kapseln.

Bei Interesse kann man sich bei mir melden

User avatar
bernd klein
Posts: 11
Joined: 13. May 2004 22:14
Location: Ritterhude

#13 Post by bernd klein »

shit die ISBN vergessen:

Addison-Wesley 3-8273-1512-3 (ca. 50€ - aber die lohnen sich!)

chrisjumper
Posts: 104
Joined: 12. Feb 2004 12:53
Location: Jülich

Guten Tag Herr Klein,

#14 Post by chrisjumper »

also erstmal danke für diesen Buchtipp. Ich hab wirklich schon daran gedacht mir ein Buch anzuschaffen, da dieses "C und Linux" Buch die einzelnen Bereiche zwar erklärt.. aber auch nicht wirklich vertieft. Vielleicht kommt das ja noch...

Werd mich einfach noch mal melden wenn ich eins der 3 Bücher aushab :o) Und mein Debian endlich geht... und ich somit wieder programmieren kann...

Hab grad Suse ohne gcc und automake... kann man sich garnicht vorstellen was :)

Entfernt
Posts: 149
Joined: 22. Jul 1999 12:53

#15 Post by Entfernt »

Darüber, wie man C++Klassen für IPC über den Shared Memory jagt, gibt es auch einen netten DeveloperWorks-Artikel: http://www-106.ibm.com/developerworks/l ... ShareLinux

Post Reply