ich rufe sie auf mit
char string[39];
addFunction(string)
In der zeile: strcpy(firstFct->functionName,functionName); springt das
Programm aber zur Laufzeit raus. woran kann das liegen?
ist es überhaupt möglich, pointer in einem struct zu nutzen?(malloc weiß
dann ja gar nicht, wie groß die struct ist.) oder muss hier bereits die
länge vordefiniert sein?
Schönen Gruß
lueis
lueis schrieb:> In der zeile: strcpy(firstFct->functionName,functionName); springt das> Programm aber zur Laufzeit raus. woran kann das liegen?
Daran, daß du keinen Speicher für die Daten bereitstellst.
firstFct->functionName ist ein Zeiger, der nicht initialisiert ist. Er
zeigt also irgendwo in den Wald. Und mit strcpy kopierst du deinen Text
nun an dieses Irgendwo.
> ist es überhaupt möglich, pointer in einem struct zu nutzen?
Ja.
> (malloc weiß dann ja gar nicht, wie groß die struct ist.)
Doch, klar weiß es das. Es reserviert eben den Platz für den Pointer.
Worauf der später mal zeigen soll, weiß aber malloc nicht. Es wird also
für deine Daten kein Speicher reserviert.
Bevor der Shitstorm los geht schreib ich etwas konstruktives.
Der Quelltext sollte zum einen so nicht kompiliert werden können, da
"firstFct" nicht in der Funktion "addFunction" definiert ist.
Zum anderen allozierst du Speicher in dem du
1
firstFct = malloc(sizeof(struct function))
aufrufst. Also zum Verständnis du hast dir mal eine Pointer Variable
1
struct function *firstFct;
angelegt und weist ihr eine gewisse Menge an Speicher zu.
Das heißt du reservierst dir Speicher für den Inhalt deiner Struktur.
Und da sind einmal ein Integer und ein Pointer auf ein Char drin.
Macht 4 Byte für den Integer und 8 Byte für die Adresse des Chars (es
ist ja ein Pointer). Jetzt kannst du aber noch lang nicht in den Pointer
des Chars einfach deine Funktionsnamen reinschreiben. Zuvor musst du,
wie bereits für deine "firstFct", Speicher allozieren auf den dein Char
Pointer verweist und in den Speicher kannst du rein schreiben.
also alloziere dir Speicher für deinen Char Pointer und schreib dann
deine Namen rein.
Und nicht vergessen zum Schluss alles "von innen nach außen" frei zu
geben. Also erst den Char Pointer, dann den Struktur Pointer.
>> in einer .h oder in einer .c stehen?
Da rätselt man wieder, weil es nur Code-Schnipsel, aber nichts richtig
gibt.
Nach der Fehlermeldung würde ich mal .h tippen.
in einer .h datei. ist
ist das nicht egal, weil header als include in c einfach reinkopiert
werden?
Ich möchte eine globale liste aus functions machen. Dabei ist firstFct
immer der Beginn. ich habe das Element
1
function*next;
oben vergessen.
Roki schrieb:> Der Quelltext sollte zum einen so nicht kompiliert werden können, da> "firstFct" nicht in der Funktion "addFunction" definiert ist.
firstFct ist global, deswegen kann auch der int-Wert beschrieben werden
Soll ich also
lueis schrieb:> ist das nicht egal, weil header als include in c einfach reinkopiert> werden?
Eben deswegen ist es nicht egal, weil header in jedes sie einbindende
C-File einfach reinkopiert werden.
In einer Headerdatei definierte Objekte werden somit bei jedem
Übersetzungsvorgang erneut angelegt - und sind somit als mehrfache Kopie
vorhanden.
Im Prinzip: ja.
Aber nicht mit sizeof.
Der String, den du hier bekommst
1
voidaddFunction(char*functionName){
2
...
hat eine Länge. Und diese Länge kann man mit strlen() feststellen.
Aber Achtung!
strlen liefert dir die tatsächliche Länge des STrings.
die strlen("Test") wäre 4. Du brauchst aber eine Speicherfläche von 5
Bytes Größe, da ja für das obligatorische abschliessende \0 Zeichen im
String auch ein Byte reserviert werden muss.
Hmm. Solltest du über die Phase des "Wie funktioniert
String-Verarbeitung in C nicht schon längst hinaus sein, wenn du dich an
dynamischen Datenstrukturen wie Listen etc. versuchst?
willst du eigentlich gar nicht so machen.
Denn wenn du mal genauer überlegst, dann musst du ja auf jeden Fall
einen Neuen Knoten für deine Liste anlegen. Unabhängig davon, ob das
jetzt der erste Knoten der Liste ist oder ob es bereits eine Liste gibt,
an die angehängt wird. Ein neuer Knoten muss auf jeden Fall erzeugt
werden. Das einzige, was unterschiedlich ist, ist wo dieser neue Knoten
eingehängt wird. In dem einen Fall kommt ein Verweis auf diesen neuen
Knoten in firstFct rein, im anderen Fall muss zuerst das Ende der
vorhandenen Liste aufgesucht werden und der neue Knoten wird in die
Liste eingehängt, in dem ein entsprechender Verweis in das next Feld des
letzten Listen-Knotens eingetragen wird.
Das sind aber 2 Paar verschiedene Schuhe. Und genau so wird man die auch
sinnvollerweise behandeln: in 2 Schritten
1
voidaddFunction(char*functionName)
2
{
3
structfunction*newNode;
4
structfunction*loop;
5
6
//
7
// neuen Knoten erzeugen
8
//
9
newNode=malloc(sizeof(structfunction));
10
if(newNode==NULL){
11
fprintf(stderr,"addFunction: Kein Speicherplatz vorhanden fuer neuen Knoten\n");
Rufus Τ. Firefly schrieb:> lueis schrieb:>> ist das nicht egal, weil header als include in c einfach reinkopiert>> werden?>> Eben deswegen ist es nicht egal, weil header in jedes sie einbindende> C-File einfach reinkopiert werden.>> In einer Headerdatei definierte Objekte werden somit bei jedem> Übersetzungsvorgang erneut angelegt - und sind somit als mehrfache Kopie> vorhanden.
Das wird mit präprozessoren in der h. dateiabgehandelt
1
#ifndef FRONT_H_DEF
2
...
3
struct{}
4
structfunction*firstFct=NULL
5
...
6
#define FRONT_H_DEF
7
...
8
#endif // FRONT_H_DEF
So wie ich das verstanden habe, führt das bei mehrmaligem includen
dazu, dass nur einmal eingebunden wird
Danke, ich habe jetzt auch erst die struktur gebaut und dann angehängt
Karl Heinz Buchegger schrieb:> Hmm. Solltest du über die Phase des "Wie funktioniert> String-Verarbeitung in C nicht schon längst hinaus sein, wenn du dich an> dynamischen Datenstrukturen wie Listen etc. versuchst?
Ich habe lange nciht mehr C programmiert und leider viel mit höheren
Sprachen gemacht. Da kommt man leicht aus dem logischen Denken raus ;)
lueis schrieb:> So wie ich das verstanden habe, führt das bei mehrmaligem includen> dazu, dass nur einmal eingebunden wird
Mehrmaliges includen in dieselbe Datei wird verhindert. Das hilft aber
nicht bei dem angesprochenen Problem.
Jede .c Datei ist eine eigene Übersetzungseinheit. Der Compiler kennt
daher keine anderen Dateien ausser den Includes.
Darum steht also in jeder .c die deine .h einbindet eine
Variablendefinition.
Diese Variable steht dann auch in in der enstsprechenden .obj
Jetzt kommt der Linker und findet in verschiedenen .obj Variablen mit
dem selben Namen. Er kann jetzt annehmen dass es wirklich dieselbe
Variable ist.
Dann darf eine Zuweisung aber nur einmal erfolgen.
Darum gehört Code der Speicher belegt nicht in eine .h