mikrocontroller.net

Forum: PC-Programmierung SQLITE sqlite3_str_reset() Seqmentfault


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Marco H. (damarco)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe ein seltsames Problem das die Funktion sqlite3_str_reset() 
einen segmentfault auslöst.

Wirklich verstehe ich das nicht, denn die Funktion sqlite3_str_reset() 
setzt den bytecounter auf null und terminiert den string. Der 
Angeforderte Speicher bleibt erhalten. Passt dieser nicht rein wird 
durch sqlite3_str_append() neuer angefordert.

Ich habe solch eine ähnliche Funktion Programmiert zum erzeugen von json 
und diese funktioniert ohne Probleme. Auch mit dem SQL Code ;)

Was ich mir vorstellen könnte das der Pointer für den String intern 
verwendet wird bzw. etwas darauf zugreift.


sqlite Version 3.22.0-1ubuntu0.1

Jemand das Problem bekannt ?
Oder ich mach etwas falsch ?


Ich werde mal mit valgrid schauen, ewt. ist man dann schlauer...


Der Code sieht beispielhaft so aus...

sqlite3_str *sql= sqlite3_str_new(db); 


if(sql){

while(BEDINGUNG){

sqlite3_str_appendf(sql,"SQL COMMAND");

/* prepare or exec SQL Command */
.....


sqlite3_str_reset(sql) /* segemntfault */

}

sqlite3_free(sqlite3_str_finish(sql));

}


von Clemens L. (c_l)


Bewertung
0 lesenswert
nicht lesenswert
Marco H. schrieb:
> Der Angeforderte Speicher bleibt erhalten.

Nein.
/*
** Reset an StrAccum string.  Reclaim all malloced memory.
*/
SQLITE_API void sqlite3_str_reset(StrAccum *p){
  if( isMalloced(p) ){
    sqlite3DbFree(p->db, p->zText);
    p->printfFlags &= ~SQLITE_PRINTF_MALLOCED;
  }
  p->nAlloc = 0;
  p->nChar = 0;
  p->zText = 0;
}

Du kannst genausogut in jedem Schleifendurchlauf eine neues Objekt 
erzeugen.

Der Grund des Problems ist wahrscheinlich anderer Code, der den Speicher 
überschreibt.

von Marco H. (damarco)


Bewertung
0 lesenswert
nicht lesenswert
Mit dem Code wird das klar.

 "The sqlite3_str_reset(X) method resets the string under construction 
inside sqlite3_str object X back to zero bytes in length."

Hier er weniger...

was macht dann sqlite3_str_finish() genau ? Es gibt ja ein Memory Objekt 
zurück welches mit  sqlite3_free() freigegeben wird.


Wenn sqlite3_str_reset(X) nicht das macht was ich dachte kann ich auch 
sqlite3_mprintf() verwenden.

Aber Danke die Antwort war schon aufschlussreich genug ich werfe mal 
einen blick in den Code.

von Marco H. (damarco)


Bewertung
0 lesenswert
nicht lesenswert
Ok ich habe es verstanden...

mit sqlite3_str_finish() wird das Object zerstört und der String 
zurückgegeben. Mit  sqlite3_free() wird der speicher vom String 
freigegeben der aus dem Object heraus gelöst wurde.

sqlite3_str_value() liefert nur einen pointer zum aktuellen String im 
Object.

sqlite3_str_reset(X) zerstört das object mit dem string. 
sqlite3_str_finish() und  sqlite3_free() ist unnötig da kein string aus 
dem Object heraus gelöst wurde und es bereits zerstört wurde.

von Clemens L. (c_l)


Bewertung
0 lesenswert
nicht lesenswert
Es gibt zwei Speicherblöcke: das sqlite3_str-Objekt, und den Puffer für 
den eigentlichen String (zText).

sqlite3_str_reset() gibt nur zText frei; das Objekt ist dann in dem 
selben Zustand, den es direkt nach sqlite3_str_new() hatte.

sqlite3_str ist nur dann sinnvoll, wenn du einen String in mehreren 
Schritten zusammensetzen willst. Für dein Programm ist sqlite3_mprintf() 
in der Tat besser.

von Marco H. (damarco)


Bewertung
0 lesenswert
nicht lesenswert
Ok verstanden ;) Vielen Dank !

Clemens L. schrieb:

> sqlite3_str_reset() gibt nur zText frei; das Objekt ist dann in dem
> selben Zustand, den es direkt nach sqlite3_str_new() hatte.

Ja aber warum kommt in dieser stelle es dann zum Seqmentfault ?
Denn genau das machte ja der Code, sqlite3_str_appendf() erzeugt einen 
neuen zText.

Ich kann ja mal schauen wo genau das Segmentfault auftritt.

: Bearbeitet durch User
von Clemens L. (c_l)


Bewertung
0 lesenswert
nicht lesenswert
Marco H. schrieb:
> Ja aber warum kommt in dieser stelle es dann zum Seqmentfault ?

Weil anderer Code (den du nicht gezeigt hast) den Speicher zerhauen hat.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.