C Speicherproblem ...
Chris
- sonstiges
Hallo zusammen,
ich habe ein komisches Problem mit einem kleinen C Programm das mir bald meinen Verstand nimmt ;-(
Ich Deklariere eine Variable "query" um diese in meiner Funtkion zu benutzen.
Aber beim ersten Durchlauf meiner Whileschleife hat die Variable den Inhalt "4{@4{@".
Beim 2ten durchlauf ist die Variable dann so wie sie eigentlich sein soll, ich kann das absolut nicht verstehen ;-(
Hier mal das Stück Code (gekürzt, aber der gleiche Effekt):
void RunJobs()
{
MYSQL_ROW row, zon;
MYSQL_RES *res,*res1;
FILE *stream;
FILE *zone;
char *str,*query;
int size=0, i;
mysql_query(mysql, "SELECT * FROM domains WHERE MID=0");
CheckError();
res = mysql_store_result(mysql);
CheckError();
mysql_field_seek (res, 0);
while ((row = mysql_fetch_row (res)) != NULL)
{
query =(char *) malloc(11);
printf("Hier der Inhalt von Query: %s\n",query);
free(query);
}
mysql_free_result(res);
}
Der Code lässt einsehen das ich dort einen Query für eine Mysql Abfrage zusammen bauen möchte, habe das ganze aber wegen der Übersicht auf das Minimum begrenzt.
Habt Ihr vieleicht Rat für mich ?
Wenn ich hier mit meiner Frage im falschen Forum gelandet bin gebt mir doch bitte einen Tipp wo ich noch schauen könnte ...
Jedenfalls danke und viele Grüße,
Chris
Moin,
query =(char *) malloc(11);
Du allozierst dynamisch Speicher. Über diesen Speicher kann man dann aber keine Aussagen machen (im Allgemeinen), er ist mit undefinierten Werten gefüllt. Wenn du willst dass da was bestimmtes drinsteht, dann musst du es reinschreiben. Oder du benutzt gleich calloc(), welches den Speicher freundlicherweise gleich ausnullt.
Hi,
danke für deine Antwort, so schaut das Ganze eigentlich aus:
while ((row = mysql_fetch_row (res)) != NULL)
{
str = "SELECT * FROM zonen WHERE DID=";
size=0;
size+=strlen(str);
size+=strlen(row[0]);
query =(char *) malloc(size + 11);
strcat(query, str);
strcat(query, row[0]);
printf("Hier der Query: %s\n",query);
free(query);
}
sollte doch eigentlich ok sein, oder ?
Ich ermittle den benötigten Speicherplatz in der Variable size, reserviere dann den Platz für query mit malloc, dann kopiere ich den Inhalt von str und row[0] in die Variable Query ;-)
Bei der ersten Ausgabe des Query schaut des so aus:
Hier der Query: 4{@4{@SELECT * FROM zonen WHERE DID=1
Nach der ersten läuft alles Prima:
Hier der Query: SELECT * FROM zonen WHERE DID=2
Hab ich da was absolut nicht verstanden ? ;-(
Viele Grüße ...
Chris
Moin,
query =(char *) malloc(size + 11);
Wie gesagt, der Inhalt des Speichers auf den query zeigt ist undefiniert (lies: auf gängigen Systemen zufällig). Bei dir steht halt zufällig 4{@4{@ gefolgt von einem Nullbyte drin.
strcat(query, str);
Damit hängst du an den aktuellen Inhalt des Strings etwas an. Das macht nichts weiter als das erste Nullbyte im String zu suchen und dahin den anderen String zu kopieren.
Hab ich da was absolut nicht verstanden ? ;-(
Offensichtlich.
Hi,
Wie gesagt, der Inhalt des Speichers auf den query zeigt ist undefiniert
Ok, Anlauf 2 ;-)
char str[50]="SELECT * FROM zonen WHERE DID=",query[61]="";
Damit lege ich dann jetzt fest das dort nichts unsinniges reinrutscht.
while ((row = mysql_fetch_row (res)) != NULL)
{
strcat(query, str);
strcat(query, row[0]);
printf("Hier der Query: %s\n",query);
}
Nun ist im Speicher das was drin sein soll, aber er hängt logischer Weise an Query immer wieder str und row[0] an, was ich aber vermeiden möchte ;-)
Daher meine Frage, wie kann ich die Variable query am Ende der Whileschleife wieder leeren ?
query=""; klappt nett, free is klar geht auch nett, aber was bleibt mir da noch ?
Viele Grüße und danke,
Chris
Hi,
Wie gesagt, der Inhalt des Speichers auf den query zeigt ist undefiniert
Ok, Anlauf 2 ;-)
char str[50]="SELECT * FROM zonen WHERE DID=",query[61]="";
Du hast alle " escaped?
Gut, geh' ich einfach mal von aus ;-)
Nun ist im Speicher das was drin sein soll, aber er hängt logischer Weise an Query immer wieder str und row[0] an, was ich aber vermeiden möchte ;-)
Daher meine Frage, wie kann ich die Variable query am Ende der Whileschleife wieder leeren ?
Einfach NULen oder ein '\0' an den Anfang setzen:
memset(str,0,strlen(str));
oder
str[0] = '\0';
query=""; klappt nett.
Klappt deshalb nicht, weil du so keinen String kopieren kannst und auch ein C-String der Länge 0 ist ein String.
so short
Christoph Zurnieden
PS:
Sag' mal: was machst Du da eigentlich? Ist ja lobenswert, das Du C lernst, aber meisnt Du nicht, das Du erstmal die Grundlagen lernen solltest bevor Du an sowas rangehst?
CZ
Hallo,
char str[50]="SELECT * FROM zonen WHERE DID=",query[61]="";
Du hast alle " escaped?
Gut, geh' ich einfach mal von aus ;-)
Na ja, ich vermute die Anweisung nach dem Kommaoperator soll so etwas wie
query[61] = '\0';
bewirken.
Nun ist im Speicher das was drin sein soll, aber er hängt logischer Weise an Query immer wieder str und row[0] an, was ich aber vermeiden möchte ;-)
Wie wäre es, wenn sich der Ausgangsposter mit den diversen String-Funktionen beschäftigt, ein Ausgangspunkt neben dem Handbuch ist z.B. http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_5.html
strcpy bzw. strncpy statt strcat wäre schon mal eine Massnahme. Ich verstehe allerdings nicht, warum der OP seinen Puffer um 11 Zeichen größer macht als den Inhalt, ein Zeichen sollte für '\0' genügen.
Ich weiss, es handelt sich um _alte_ Informationen. Aber soviel hat sich da nicht getan :-)
Freundliche Grüsse,
Vinzenz
Hi,
Nun ist im Speicher das was drin sein soll, aber er hängt logischer Weise an Query immer wieder str und row[0] an, was ich aber vermeiden möchte ;-)
Wie wäre es, wenn sich der Ausgangsposter mit den diversen String-Funktionen beschäftigt, ein Ausgangspunkt neben dem Handbuch ist z.B. http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_5.html
strcpy bzw. strncpy statt strcat wäre schon mal eine Massnahme.
Na, so einfach ist das alles nicht.
Ich verstehe allerdings nicht, warum der OP seinen Puffer um 11 Zeichen größer macht als den Inhalt, ein Zeichen sollte für '\0' genügen.
Na, doch, das ist schon verständlich, wenn man den ganzen Thread verfolgt hat ;-)
Ich weiss, es handelt sich um _alte_ Informationen. Aber soviel hat sich da nicht getan :-)
Die neueste ist hier:
http://www.gnu.org/software/libc/manual/
Ist aber auch schon recht alt.
so short
Christoph Zurnieden
Hi,
Du hast alle " escaped?
Gut, geh' ich einfach mal von aus ;-)
Öhm, nein ;-)
Aber in dem String kommen keine ' oder " vor, oder meinst du was anderes ?
str[0] = '\0';
Klappt bestens, danke ;-)
PS:
Sag' mal: was machst Du da eigentlich? Ist ja lobenswert, das Du C lernst, aber meisnt Du nicht, das Du erstmal die Grundlagen lernen solltest bevor Du an sowas rangehst?
CZ
Das ganze ist/wird eine Verwaltung (html,php,mysql) für Zonefiles.
Ist wahrlich mein erster Versuch etwas in C zu schreiben ...
Das mit den Grundlagen ist so eine Sache, wenn ich mir das alles nur trocken durchlese bleibt kaum was hängen, daher lerne ich quasie mit der Aufagabe ;-)
Hast du vieleicht eine Info wo ich ein Forum finden kann das sich intensiver mit dem Thema C beschäftigt wo ich auch im Arhciv ein bisel lesen kann ?
Meist sind ja die Anfängerfragen immer die gleichen ;-)
Viele Grüße & danke,
Chris
Hi,
Du hast alle " escaped?
Gut, geh' ich einfach mal von aus ;-)Öhm, nein ;-)
Aber in dem String kommen keine ' oder " vor, oder meinst du was anderes ?
Ja, ich meine 'was anderes.
Aber der Witz scheint ja nicht gut rauszukomen, wenn gleich zwei Leute das nicht komisch finden, was? ;-)
Jaja, sagt man's mal durch die Blume ... ;-)
str[0] = '\0';
Klappt bestens, danke ;-)
Ja, das funktioneirt. Ist aber kein wirklich guter Stil, da so die Reste im Speicher verbleiben. Ist in 99,99% der Fälle egal, aber wenn Du mal z.B. Paßwörter auf diese Weise löscht ...
Nein, nimm besser memset()
PS:
Sag' mal: was machst Du da eigentlich? Ist ja lobenswert, das Du C lernst, aber meisnt Du nicht, das Du erstmal die Grundlagen lernen solltest bevor Du an sowas rangehst?
CZDas ganze ist/wird eine Verwaltung (html,php,mysql) für Zonefiles.
Und warum dann C?
Nein, ernsthafte Frage: warum brauchst Du etwas in C?
Ist wahrlich mein erster Versuch etwas in C zu schreiben ...
Ja, das ist bemerkenswert auffällig ;-)
Soll Dich aber natürlich nicht davon abhalten!
Das mit den Grundlagen ist so eine Sache, wenn ich mir das alles nur trocken durchlese bleibt kaum was hängen, daher lerne ich quasie mit der Aufagabe ;-)
Ja, das kann ich gut nachvollziehen ;-)
Hast du vieleicht eine Info wo ich ein Forum finden kann das sich intensiver mit dem Thema C beschäftigt wo ich auch im Arhciv ein bisel lesen kann ?
Keine Ahnung, bin ich ehrlich. Sowas hier?
news:alt.comp.lang.learn.c-c++
Google Cache dieser Newsgroup:
http://groups.google.de/groups?hl=de&lr=&ie=ISO-8859-1&q=alt.comp.lang.learn.c-c%2B%2B&btnG=Suche
Meist sind ja die Anfängerfragen immer die gleichen ;-)
C-FAQ
http://www.eskimo.com/~scs/C-faq/top.html
Eine kurze Buchliste:
http://www.comeaucomputing.com/booklist/
Tutorials:
Das Berühmte:
http://www.lysator.liu.se/c/bwk-tutor.html
Der "Klassiker"
http://www.cs.cf.ac.uk/Dave/C/CE.html
Hat so einen netten Namen ;-)
http://www.strath.ac.uk/IT/Docs/Ccourse/
Eien lose Sammlung vom Maintainer der C-FAQ
http://www.eskimo.com/~scs/cclass/cclass.html
Etwas in deutsch:
http://www.schellong.de/c.htm
http://www.lemps.ch/doku/
Ansonsten kannst Du mich ja auch noch löchern ;-)
so short
Christoph Zurnieden
hi!
while ((row = mysql_fetch_row (res)) != NULL)
{
query =(char *) malloc(11);
printf("Hier der Inhalt von Query: %s\n",query);
free(query);
}
Dass du query hier gar keinen Wert zuweist, sondern einfach einen zufälligen Bereich
im Speicher (inkl. dessen Inhalt), hat Henryk dir ja schon geschrieben. Aber außerdem
möchtest du sehr wahrscheinlich den Rückgabewert von malloc() nicht casten!
bye, Frank!
Hi,
Aber außerdem
möchtest du sehr wahrscheinlich den Rückgabewert von malloc() nicht casten!
Warum nicht? Es ist nicht verboten und C++ braucht es. Woher wilst Du wissen, das deer gesamte Code nicht in C++ genutzt werden soll?
http://www.google.com/groups?selm=9sFIb.9066%24nK2.4505%40nwrddc01.gnilink.net&output=gplain
Gut, war ja auch nur 'ne rethorische Frage ;-)
so short
Christoph Zurnieden
hi!
Aber außerdem
möchtest du sehr wahrscheinlich den Rückgabewert von malloc() nicht casten!
Warum nicht? Es ist nicht verboten und C++ braucht es. Woher wilst Du wissen, dass
der gesamte Code nicht in C++ genutzt werden soll?
In C++ würde man weder malloc() noch C-Casts verwenden.
bye, Frank!
Hallo Chris,
Aber beim ersten Durchlauf meiner Whileschleife hat die Variable den Inhalt "4{@4{@".
Das ist Zufall.
Beim 2ten durchlauf ist die Variable dann so wie sie eigentlich sein soll, ich kann das absolut nicht verstehen ;-(
Das ist ebenfalls Zufall.
char *str,*query;
Warum nicht
char query[11];
while ((row = mysql_fetch_row (res)) != NULL)
{
query =(char *) malloc(11);
Du allozierst dynamisch Speicher. Es könnte fehlschlagen. Prüfst Du den Erfolg der Anforderung?
printf("Hier der Inhalt von Query: %s\n",query);
Es ist Zufall, was in dem Speicher steht. Bei der Verwendung von
calloc
würden Nullen drin stehen. Mir ist allerdings schleierhaft, warum Du dynamisch Speicher anforderst. Hier ist meiner Meinung nach ein statischer Puffer sinnvoller. Die Doku zu malloc und calloc findest Du bei einem Linux-System mit
man malloc
Freundliche Grüsse,
Vinzenz