Forum: PC-Programmierung wie finde ich das Speicherleak?


von Maik G. (maik81ftl)


Angehängte Dateien:

Lesenswert?

Moin Moin,

da ich nun einige Grundlagen soweit gefressen habe -.- hänge ich gerade
bei dem Problem, das ich in dem folgende code irgendwo ein Speicherleak
auftut. :(

Hier erst mal der code!
1
char *ctb(unsigned short usocfe) // *usocfe = Zeiger "unsigned short of cfe"
2
{
3
  char *bin = malloc(sizeof(char)* (9+1));
4
  char *temp = malloc(sizeof(char)* (9+1));
5
  int a;
6
  for (a=7; a>=0; --a)
7
    {
8
    switch (usocfe%2)
9
      {
10
      case 0: usocfe=usocfe/2;
11
              strcpy(temp, "0");
12
              break;
13
      case 1: usocfe=usocfe/2;
14
              strcpy(temp, "1");
15
              break;
16
      }
17
    strcat(bin, temp);
18
    }
19
  free(temp);
20
  return(bin);
21
}

ich vermude ein Speicherleak in dieser function. wie ich darauf komme???

> ==8111== Conditional jump or move depends on uninitialised value(s)
> ==8111==    at 0x4C2836A: strcat (mc_replace_strmem.c:176)
> ==8111==    by 0x4006F5: ctb (in
> home/maik81ftl/Programming/viaC/Test2/Laufende-Programme/Test1/Wandela)
> ==8111==    by 0x40075B: main (in
> /home/maik81ftl/Programming/viaC/Test2/Laufende-Programme/Test1/Wandela)
> ==8111==
1
//char *main(const char *cfe) //*cfe = Zeiger "char from extern"
2
void main() // NUR FÜR TESTZWECKE
3
{
4
//  char *_cfe = malloc(sizeof(char) * (strlen(cfe) + 1));  // speichergröße resavieren.
5
  char *_cfe = "AB";                                      // NUR FÜR TESTZWECKE
6
//  strcpy(_cfe, cfe);
7
  int a=0;                                                
8
  printf("\nMoin : %s\n", _cfe);
9
  while(_cfe[a])      // Beispielschleife für eine zeichenweise ausgabe
10
    {    
11
      printf("Wert?! %s \n\n", ctb((unsigned short) _cfe[a]));
12
      printf(" %c == %hu ", _cfe[a++], (unsigned short)_cfe[a]);
13
    }
14
  free(_cfe);
15
}

der Vollständigkeitshalber habe ich hier noch den komplette 
Konsolenausdruck als Anhang beigefügt.

von ggast (Gast)


Lesenswert?

Ich nenne das mal "Chaoscode"...

GCC sagt:
1
warning: operation on `a' may be undefined
für Zeile
1
Zeile printf(" %c == %hu ", _cfe[a++], (unsigned short)_cfe[a]);
Debugger sagt:
1
DEBUG: ERROR: main.c: free(_cfe): Es wurde versucht Speicher an Adresse 0x00405BBa freizugeben welcher nicht mittels malloc() oder realloc() angefordert wurde.

Was soll das werden?!?

von Klaus (Gast)


Lesenswert?

Naja, überlege mal:

Ignoriere zunächst mal die Speicherzuweisungen an "temp".
Wie oft wird jetzt beim Ausführen von:
1
  while(_cfe[a])      // Beispielschleife für eine zeichenweise ausgabe
2
    {    
3
      printf("Wert?! %s \n\n", ctb((unsigned short) _cfe[a]));
4
      printf(" %c == %hu ", _cfe[a++], (unsigned short)_cfe[a]);
5
    }
6
  free(_cfe);

malloc() und wie oft wird free() aufgerufen?

von Vlad T. (vlad_tepesch)


Lesenswert?

Maik Geßner schrieb:
> char *_cfe = "AB";
Maik Geßner schrieb:
> free(_cfe);

du free-st eine stackvariable

Maik Geßner schrieb:
> char *ctb(unsigned short usocfe) // *usocfe = Zeiger "unsigned short of cfe"
> {
>   char *bin = malloc(sizeof(char)* (9+1));
>   return(bin);
> }


Maik Geßner schrieb:
> printf("Wert?! %s \n\n", ctb((unsigned short) _cfe[a]));

du allozierst in einer Funktion, speicher, den du rausgibst, der aber 
außerhalb weder gespeichert, noch freigegeben wird


Maik Geßner schrieb:
> char *temp = malloc(sizeof(char)* (9+1));
was soll eigentlich der Quatsch?
warum nicht einfach
char temp[(9+1)];



Maik Geßner schrieb:
> char *ctb(unsigned short usocfe) // *usocfe = Zeiger "unsigned short of cfe"
was der Kommentar bedeuten soll, weiß wahrscheinlich auch keiner.

Der Rest der funktion ist auch kompletter schrott.
Beschäftige dich bitte nochmal mit C-Strings, char und 
Stringoperationen.

von Peter II (Gast)


Lesenswert?

wozu überhaupt tmp dynamisch alloklieren?

char bin[9+1];

damit würde auch das free entfallen

von Maik G. (maik81ftl)


Lesenswert?

Klaus schrieb:
> Naja, überlege mal:
>
> Ignoriere zunächst mal die Speicherzuweisungen an "temp".
> Wie oft wird jetzt beim Ausführen von:
>
>
1
>   while(_cfe[a])      // Beispielschleife für eine zeichenweise ausgabe
2
>     {
3
>       printf("Wert?! %s \n\n", ctb((unsigned short) _cfe[a]));
4
>       printf(" %c == %hu ", _cfe[a++], (unsigned short)_cfe[a]);
5
>     }
6
>   free(_cfe);
7
>
>
> malloc() und wie oft wird free() aufgerufen?

abgesehen von dem befehl
1
free(_cfe);
, den ich mal spaßeshalber auszukommentiert habe, obwohl dieser zur der 
Zeile
1
//  char *_cfe = malloc(sizeof(char) * (strlen(cfe) + 1));  // speichergröße resavieren.
gehört, habe ich nachwievor noch die selbe anzahl an Speicherleaks.

*ggf. sollte man auch mal die kommentare lesen*

1
//char *main(const char *cfe) //*cfe = Zeiger "char from extern"
2
void main() // NUR FÜR TESTZWECKE
3
{
4
//  char *_cfe = malloc(sizeof(char) * (strlen(cfe) + 1));  // speichergröße resavieren.
5
  char *_cfe = "AB";                                      // NUR FÜR TESTZWECKE
anhand dieser läst sich eindeutisch erkennen, wie das Teil einmal 
aussehen soll.

von ggast (Gast)


Lesenswert?

ggast schrieb:
> Was soll das werden?!?

Vorsichtshalber: Netiquette

von Vlad T. (vlad_tepesch)


Lesenswert?

Peter II schrieb:
> char bin[9+1];

das bin darf nicht lokal definert werden, das wird ja zurückgegeben.

Normalerweise macht man sowas aber trotzdem nicht, sondern übergibt der 
Funktion einen Puffer, der beschrieben werden kann.
Normalerweise gilt die Regel: Es gibt der den speicher Frei, der ihn 
auch alloziert hat.


Hab ich den Kot eigentlich richtig interpretiert, wenn ich der Meinung 
bin, es soll ein Bitmuster als String zurückgegeben werde?

Falls ja:
warum nimmt die funktion Shorts, wenn sie nur 8bit umwandelt?
Außerdem ist das ergebnis verkehrt rum. Das niederwertige bit wird hier 
als erstes ausgegeben.

Hier mal ein kleines Beispiel vernünftigen Codestils
1
/**
2
 *  Converts a given byte to string of its binary representation
3
 *  @param o_dest  the buffer that receives the resulting string
4
 *                 Has to be at least 9 bytes long.
5
 *  @param i_byte  the byte to convert
6
 */
7
void byteToBinString(char* o_dest, unsigned char i_byte)
8
{
9
  signed char i = 7;
10
  for(; i>0; --i)
11
  {
12
    char curBit = (i_byte & 1);  // linkestes Bit auslesen
13
    o_dest[i] = curBit + '0';  // einfache Konvertierung Zahl->char für zahl < 10  und schreiben des Characters an aktuelle stelle
14
    i_byte >>= 1;  // alle bits nach rechts schieben
15
  }
16
  o_dest[8] = '\0';
17
}

von Peter II (Gast)


Lesenswert?

Vlad Tepesch schrieb:
> Peter II schrieb:
>> char bin[9+1];
>
> das bin darf nicht lokal definert werden, das wird ja zurückgegeben.

sorry meine temp wie auch schon oben jemand anders geannt hatte.

von ggast (Gast)


Lesenswert?

Vlad Tepesch schrieb:
> Hab ich den Kot eigentlich richtig interpretiert
Ist das jetzt Absicht oder ein Tippfehler?

von Vlad T. (vlad_tepesch)


Lesenswert?

ggast schrieb:
> Ist das jetzt Absicht oder ein Tippfehler?
rate mal


Vlad Tepesch schrieb:
> char curBit = (i_byte & 1);  // linkestes Bit auslesen

sorry, sollte natürlich rechtestes heißen.
Ich wollts erst andersrum schieben und auslesen

Prinzipiell sei noch zu sagen, dass solche Kommentare nicht sehr 
sinnvoll sind, da man eher beschreiben soll, warum etwas gemacht wird, 
und nicht der Code nochmal übersetzt werden soll.
Da hier aber die Grundkenntnisse noch recht wackelig zu sein scheinen, 
hab ichs trotzdem so gemacht.

von Klaus (Gast)


Lesenswert?

> dieser läst sich eindeutisch erkennen, wie das Teil einmal
> aussehen soll.

Nein, das ist ein Gewurstel^3 hier kann niemand irgendetwas eindeutiG 
erkennen. Gäbe es einen Geigerzähler für die Anzahl der Fehler pro Zeile 
hätte dein Code Werte wie in Fukushima. Sorry.

Fakt ist: Jedes mal bei dem du in der Schleife die Funktion ctb() 
aufrufst wird durch
1
  char *bin = malloc(sizeof(char)* (9+1));
Speicher allokiert. Diesen gibst du nie frei -> Speicherleck.

Desweiteren: Du initialisierst den Speicher in "bin" nicht benutzt 
später aber strcat(). Der Speicher muss nicht mit 0 vorinitialisiert 
sein. Dadurch  schreibt strcat() wild in den Speicher, da es zunächst 
das Ende des String sucht (eine ASCII-0) und danach schreibt.

> printf(" %c == %hu ", _cfe[a++], (unsigned short)_cfe[a]);
Das Ergebnis dieser Zeile ist btw undefiniert!

Schöne Grüße

von U.R. Schmitt (Gast)


Lesenswert?

Zusätzlich zu den schon beschriebenen Fehlern ist es IMMER sinnvoll nach 
einem malloc() zu prüfen ob der erhaltene Zeiger wirklich ungleich NULL 
ist!

von Vlad T. (vlad_tepesch)


Lesenswert?

U.R. Schmitt schrieb:
> Zusätzlich zu den schon beschriebenen Fehlern ist es IMMER sinnvoll nach
> einem malloc() zu prüfen ob der erhaltene Zeiger wirklich ungleich NULL
> ist!

macht das wirklich so viel Sinn?
wenn der Rechner so voll ist, dass man nicht mal mehr ein paar Byte 
holen kann, dann hast du eh verloren, dann ist RAM+Swap voll.

Auf µCs oder wenn man Speicher im Megabytebereich anfordert ok, aber 
sonst.

von Maik G. (maik81ftl)


Lesenswert?

@Vlad Tepesch

> Prinzipiell sei noch zu sagen, dass solche Kommentare nicht sehr
> sinnvoll sind, da man eher beschreiben soll, warum etwas gemacht wird,
> und nicht der Code nochmal übersetzt werden soll.

Das weiß ich, Aber für mich ist in dem falle aus Persönlicher ordnung 
auch die GROß- und kleinschreibung wichtig. GROß = änderung klein = 
info/aufgabe

@klaus

das Hier
1
char *bin = malloc(sizeof(char)* (9+1));
 das leak auftritt vermute ich auch, aber wie du hier
1
return(bin);
 gebe ich bin über. soll ich ihn nun vor oder nach der zeile wieder 
freigeben? vor der zeile lohnt nicht, da sonst inhalt weg.
Nach der zeile macht wohl auch nicht wirklich sin.

ergo entweder in eine header schreiben oder global.
>> printf(" %c == %hu ", _cfe[a++], (unsigned short)_cfe[a]);

Irtum... wenn ich mir der Bleistift und papier methode das alles 
durchspiele und || in die konsole schauen lese ich
> Moin : AB
> Wert?! 10000010
> Wert?! 01000010

von Peter II (Gast)


Lesenswert?

Vlad Tepesch schrieb:
> macht das wirklich so viel Sinn?

es macht inner sinn eine Fehlerbehandlung einzubauen!

von Maik G. (maik81ftl)


Lesenswert?

Ähmmm wer hat gerade mit µC angefangen??? auf die finger hau...

ich eine Function auf Konsolenebene für ein Programm.

ergo später soll dies in ein *.so/*.dll übertragen werden.

von Vlad T. (vlad_tepesch)


Lesenswert?

Maik Geßner schrieb:
> Das weiß ich, Aber für mich ist in dem falle aus Persönlicher ordnung
> auch die GROß- und kleinschreibung wichtig. GROß = änderung klein =
> info/aufgabe

das bezog sich eigentlich auf meine Kommentare.
Bei dir gibts ja fast keine und die, die es gibt sind falsch oder 
unverständlich.

Maik Geßner schrieb:
> das leak auftritt vermute ich auch, aber wie du hierreturn(bin); gebe ich bin 
über. soll ich ihn nun vor oder nach der zeile wieder
> freigeben? vor der zeile lohnt nicht, da sonst inhalt weg.
vor der Zeile darf nicht
> Nach der zeile macht wohl auch nicht wirklich sin.
nach der Zeile geht nicht

du musst den Rückgabewert der Funktion speichern, dann benutzen und dann 
freigeben.

Aber wie gesagt:

Vlad Tepesch schrieb:
> Normalerweise macht man sowas aber trotzdem nicht, sondern übergibt der
> Funktion einen Puffer, der beschrieben werden kann.
> Normalerweise gilt die Regel: Es gibt der den speicher Frei, der ihn
> auch alloziert hat.

von Vlad T. (vlad_tepesch)


Lesenswert?

Maik Geßner schrieb:
> Ähmmm wer hat gerade mit µC angefangen??? auf die finger hau...
> ich eine Function auf Konsolenebene für ein Programm.
> ergo später soll dies in ein *.so/*.dll übertragen werden.

Kannst du das nochmal für die übersetzen, deren Glaskugel kaputt ist und 
auch nicht über hellseherische Talente verfügen.

von U.R. Schmitt (Gast)


Lesenswert?

Vlad Tepesch schrieb:
> annst du das nochmal für die übersetzen, deren Glaskugel kaputt ist und
> auch nicht über hellseherische Talente verfügen.

Das Ganze ist für ein Konsolenprogramm für den PC gedacht, entweder 
Linux oder Windows, und soll warum auch immer in einer shared library 
(.so) oder DLL Datei enden, was für das Problem natürlich ohne Relevanz 
ist.

von Vlad T. (vlad_tepesch)


Lesenswert?

hat jemand etwas anders behauptet?

von U.R. Schmitt (Gast)


Lesenswert?

Ansonsten gilt, was Vlad gesagt hat.
Etwas Hirnschmalz in das Design stecken.

Normalerweise alloziert man den Speicher im aufrufenden Programm, 
übergibt einen Zeiger auf den Speicher und die Größe des Speichers an 
das Unterprogramm das dann was auch immer in den Speicher schreibt.

Es geht auch anders, wenn z.B. das aufrufende Programm die Daten und die 
Größe nicht genau kennt, Beispiel File Schnittstelle. Dann schreibt man 
aber gewöhnlich eine komplette gekapselte API die den Freigabeprozess 
mit beinhaltet. Der Aufrufer ist dann dafür zuständig das auch in jedem 
Fall zu gewährleisten.
Im Fall FILE ist das fopen() und fclose().

von Mark B. (markbrandis)


Lesenswert?

Maik Geßner schrieb:
> soll ich ihn nun vor oder nach der zeile wieder freigeben?

Weder noch. Du allozierst den Speicher im Hauptprogramm, und übergibst 
einen Zeiger auf den reservierten Speicher an die Funktion. Sobald der 
Speicherbereich im Hauptprogramm nicht mehr benötigt wird, wird er 
freigegeben.

von U.R. Schmitt (Gast)


Lesenswert?

Vlad Tepesch schrieb:
> hat jemand etwas anders behauptet?
???
Du hast doch geschrieben:

Vlad Tepesch schrieb:

> Maik Geßner schrieb:
>> Ähmmm wer hat gerade mit µC angefangen??? auf die finger hau...
>> ich eine Function auf Konsolenebene für ein Programm.
>> ergo später soll dies in ein *.so/*.dll übertragen werden.
>
> Kannst du das nochmal für die übersetzen, deren Glaskugel kaputt ist und
> auch nicht über hellseherische Talente verfügen.

Also habe ich angenommen du hättest das nicht verstanden.

von U.R. Schmitt (Gast)


Lesenswert?

Mark Brandis schrieb:
> Du allozierst den Speicher im Hauptprogramm, und übergibst
> einen Zeiger auf den reservierten Speicher an die Funktion.

Sauber ist es wenn man auch die Größe des Speichers an das Unterprogramm 
mit übergibt.

von Klaus (Gast)


Lesenswert?

Maik Geßner schrieb:
> gebe ich bin über. soll ich ihn nun vor oder nach der zeile wieder
> freigeben? vor der zeile lohnt nicht, da sonst inhalt weg.
> Nach der zeile macht wohl auch nicht wirklich sin.

Wenn du ihn davor freigibt erzeugt der Aufrufer der Funktion eine memory 
access violation wenn er auf die zurückgegebene Speicheradresse 
zugreift. Wenn du ihn nicht freigibst (wie es jetzt ist) übergibst du 
dem Aufrufer die Verpflichtung den Speicher freizugeben. Dies tut er 
hier nicht, da das Ergebnis direkt in printf() landet
1
printf("Wert?! %s \n\n", ctb((unsigned short) _cfe[a]));
und die Adresse danach verloren ist. Du müßtest du Rückgabe von ctb() in 
einem Pointer zwischenspeichern, diesen printf() übergeben und danach 
free() aufrufen.

Maik Geßner schrieb:
> Irtum... wenn ich mir der Bleistift und papier methode das alles
> durchspiele und || in die konsole schauen lese ich
1
printf(" %c == %hu ", _cfe[a++], (unsigned short)_cfe[a]);

Angenommen a ist 0. Du gehst von folgender Reihenfolge aus:
a) Erster Parameter wird geholt, also _cfe[0]
b) a++ wird gebildet
c) Zweiter Parameter wird geholt, also _cfe[1]
d) Funktionsaufruf

Die Reihenfolge mit der Parameter verarbeitet werden garantiert dir der 
Compiler aber nicht. Je nach Compiler/Plattform kann es auch anders 
herum laufen, und zwar so:
a) Zweiter Parameter wird geholt, also _cfe[0]
b) Erster Parameter wird geholt, also _cfe[0]
c) a++ wird gebildet
d) Funktionsaufruf

Du siehst dass dies unterschiedliche Resultate sind auch mit Bleistift. 
Deshalb habe ich gesagt, dass das Ergebnis dieser Zeile undefiniert ist.

Wikipedia zitiert übrigens ein ähnliches Negativbeispiel von Kernighan 
and Ritchie:
http://en.wikipedia.org/wiki/Undefined_behavior

von Peter II (Gast)


Lesenswert?

was soll daran nicht sauber sein wenn ein eine funktion einen Zeiger 
zurückliefert? Es muss nur klar sein das dieser zeiger auch wieder 
Freigeben werden muss.

malloc macht doch auch nichts anderes, es liefert einen zeiger zurück 
der mit free wieder freigeben werden muss.

von Mark B. (markbrandis)


Lesenswert?

U.R. Schmitt schrieb:
> Sauber ist es wenn man auch die Größe des Speichers an das Unterprogramm
> mit übergibt.

Ja.

Im übrigen, eine Funktion mit einem Dutzend Zeilen Code, die weder 
Massen an Hauptspeicher benötigt noch unheimlich viel Rechenzeit oder 
Zugriff auf ein Dateisystem, sollte auf einem kleinen µC genau so 
einsetzbar sein wie auf einem PC. Ohne große Änderung. Am besten mit gar 
keiner :)

Übrigens übrigens, es gibt kein Speicherleak, sondern nur ein memory 
leak oder Speicherleck. ;)

von Klaus (Gast)


Lesenswert?

Peter II schrieb:
> was soll daran nicht sauber sein wenn ein eine funktion einen Zeiger
> zurückliefert? Es muss nur klar sein das dieser zeiger auch wieder
> Freigeben werden muss.

Es ist schlechter Stil, weil das passieren kann was in diesem Beispiel 
hier passiert (Freigabe wird vergessen). In diesem konkreten Fall hier 
ist es außerdem völlig unnötig, da die benötigte Speichergröße von vorne 
herein feststeht. Als "good practice" würde man die Funktion wie folgt 
definieren:
1
unsigned int ctb(char* buffer, unsigned int size);

Der Speicher und dessen Größe kommt von außen. Die Rückgabe wird 
typischerweise die Anzahl der geschriebenen Zeichen angeben.

von Vlad T. (vlad_tepesch)


Lesenswert?

Klaus schrieb:
> unsigned int ctb(char* buffer, unsigned int size);

du hast das hauptargument vergessen ;)

von Klaus (Gast)


Lesenswert?

Vlad Tepesch schrieb:
> Klaus schrieb:
>> unsigned int ctb(char* buffer, unsigned int size);
>
> du hast das hauptargument vergessen ;)

g stimmt :-)

@Maik

Noch ein kleiner Tipp: Suche und benutze mal "SPLint". Es hat die 
meisten deiner Fehler gefunden, z.B. zu
1
printf(" %c == %hu ", _cfe[a++], (unsigned short)_cfe[a]);
meint es:
1
crap.c(36,29): Argument 2 modifies a, used by argument 3 (order of evaluation
2
    of actual parameters is undefined): printf(" %c == %hu ", _cfe[a++],
3
    (unsigned short int)_cfe[a])
4
  Code has unspecified behavior. Order of evaluation of function parameters or
5
  subexpressions is not defined, so if a value is used and modified in
6
  different places not separated by a sequence point constraining evaluation
7
  order, then the result of the expression is unspecified. (Use -evalorder to
8
  inhibit warning)

von Maik G. (maik81ftl)


Lesenswert?

Da versteh ich aber eines nicht

im folgend code, was ja der Grundgedanke war geht's ohne Speicherleck.
1
char *Testfkt(const char *sValue)
2
{
3
  printf("\nsValue : %hu\n", (unsigned short)*sValue);         // Ausgabe des dezimalen wertes von sValue! bei "A = 65" !!!
4
  char *zeichen = malloc(sizeof(char) * (strlen(sValue) + 1)); // speichergröße resavieren.
5
  strcpy(zeichen, sValue);
6
  return(zeichen);
7
}
8
9
int main()
10
{
11
  char *text = Testfkt("Ich bin ein kleiner tester");
12
  int a=0;
13
  printf("\nMoin :\n");
14
  while(text[a])      // Beispielschleife für eine zeichenweise ausgabe
15
    printf("        %c == %hu\n", text[a++], (unsigned short)text[a]);
16
  free(text);
17
}

liegt das ggf hier nur daran, das ich dem Zeiger *text schon foher eine 
constande mitgebe?

Dann noch, da einige sagten! die Größe des Speichers gleich mit geben. 
Leicher gesagt als getan -.-, der eigendlich wert, soll ja von einem 
Programm, welches unter Lazarus-IDE geschrieben wird übergeben werden.
die Bibliothek schreibe ich deshalb nur in C, weil via pfc bei der 
selben function schon ü 1,5 MB zusammen kommen. Den speicher, welche die 
Biliothek dann braucht soll angand des Wertes ermittelt werden.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Maik Geßner schrieb:
> liegt das ggf hier nur daran, das ich dem Zeiger *text schon foher eine
> constande mitgebe?


Wo tust Du das? Im Codebeispiel von eben tust Du genau das nicht.

Kauf Dir ein C-Buch, und lies es durch. Wirklich.

Empfehlung: "Programmieren in C" von Brian Kernighan & Dennis Ritchie, 
2. Ausgabe, erschienen im Hanser-Verlag.

Ist zwar 20 Jahre alt, aber immer noch das Grundlagenwerk, das Dir 
alles beibringt, was Du über C wissen musst. Und lesbar ist diese 
Ausgabe auch noch (ganz im Gegenteil zur noch älteren ersten Ausgabe).

von Klaus (Gast)


Lesenswert?

Maik Geßner schrieb:
> Da versteh ich aber eines nicht
>
> im folgend code, was ja der Grundgedanke war geht's ohne Speicherleck.

Ein Speicherleck entsteht in diesem auch nicht. Die undefiniert 
verhaltende
printf() Anweisung ist da aber auch drin.

Ich denke aber man hat dir in diesem Thread genügend Informationen 
gegeben und dir die Lösung auf dem Silbertablett serviert. Du solltest 
das Problem leicht selbst lösen können. Die Lektüre eines C Buches ist 
dennoch dringend anzuraten.

von Maik G. (maik81ftl)


Lesenswert?

@klaus jetzt hab ich geschnallt, was du mir wieso du grade auf die Zeile
1
printf("Wert?! %s \n\n", ctb((unsigned short) _cfe[a]));
 gekommen bist.

allerdings auch nur nach dem ich aus
1
char *_cfe = "AB";
1
char *_cfe = "ABCDEFGabcdefg";
 gemacht habe.

> Die Lektüre eines C Buches ist dennoch dringend anzuraten.

ok! ich verwende zwar schon die ganz Zeit 
http://http://www.buch.de/buch/00861/419_c_programmierung_lernen_.html 
aber das verrat ich mal lieber nicht -.-

von Maik G. (maik81ftl)


Lesenswert?

darf Geschloßen werden...

von asdfghjhjklä (Gast)


Lesenswert?

Frage: wie finde ich das Speicherleak?

Antwort: Wenn du schon so fragst: Vermutlich überhaupt nicht

von Lukas K. (carrotindustries)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Empfehlung: "Programmieren in C" von Brian Kernighan & Dennis Ritchie,
> 2. Ausgabe, erschienen im Hanser-Verlag.

Haben die Übersetzer dazugelernt? In meiner Ausgabe von '83 ist von 
einer 'Standard Bücherei' und, wenn ich mich recht erinnere, von 'Schnur 
Funktionen' Rede.

von Mark B. (markbrandis)


Lesenswert?

Luk4s K. schrieb:
> Haben die Übersetzer dazugelernt? In meiner Ausgabe von '83 ist von
> einer 'Standard Bücherei' und, wenn ich mich recht erinnere, von 'Schnur
> Funktionen' Rede.

"Standard library" und "string functions"? Oh Gott wie schlecht. Das 
kommt eben dabei heraus, wenn der Übersetzer keine Ahnung von der 
Materie hat - gut, man kann nicht alles wissen - aber wenn dann auch 
noch niemand mit Ahnung Korrektur liest... :-(

von Vlad T. (vlad_tepesch)


Lesenswert?

Luk4s K. schrieb:
> In meiner Ausgabe von '83 ist von
> einer 'Standard Bücherei' und, wenn ich mich recht erinnere, von 'Schnur
> Funktionen' Rede.

*rofl* 

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Luk4s K. schrieb:
> Haben die Übersetzer dazugelernt? In meiner Ausgabe von '83 ist von
> einer 'Standard Bücherei' und, wenn ich mich recht erinnere, von 'Schnur
> Funktionen' Rede.

Ja, das ist die erste Ausgabe, die ist in der Übersetzung wirklich 
grauenerregend.
Fast, als hätte sich daran eine frühe Version eines 
Übersetzungsprogrammes versucht, "Zeiger Variable" wird im Deutschen 
immer noch zusammengeschrieben, und wurde in den 80ern erst recht 
zusammengeschrieben.

Die zweite Ausgabe von 1990 oder 1989 beschreibt einerseits nicht mehr 
das steinzeitliche "K&R-C" ohne Typprüfung, sondern ANSI-C bzw. C89, und 
ist erheblich besser übersetzt. Auch wird für Codebeispiele keine 
Proportionalschrift mehr verwendet.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.