SQLITE sqlite3_str_reset() Seqmentfault

OP #6051690
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...
1
sqlite3_str *sql= sqlite3_str_new(db); 
2

3

4
if(sql){
5

6
while(BEDINGUNG){
7

8
sqlite3_str_appendf(sql,"SQL COMMAND");
9

10
/* prepare or exec SQL Command */
11
.....
12

13

14
sqlite3_str_reset(sql) /* segemntfault */
15

16
}
17

18
sqlite3_free(sqlite3_str_finish(sql));
19

20
}
#6051766
Lesenswert?

Marco H. schrieb:
> Der Angeforderte Speicher bleibt erhalten.

Nein.
1
/*
2
** Reset an StrAccum string.  Reclaim all malloced memory.
3
*/
4
SQLITE_API void sqlite3_str_reset(StrAccum *p){
5
  if( isMalloced(p) ){
6
    sqlite3DbFree(p->db, p->zText);
7
    p->printfFlags &= ~SQLITE_PRINTF_MALLOCED;
8
  }
9
  p->nAlloc = 0;
10
  p->nChar = 0;
11
  p->zText = 0;
12
}

Du kannst genausogut in jedem Schleifendurchlauf eine neues Objekt 
erzeugen.

Der Grund des Problems ist wahrscheinlich anderer Code, der den Speicher 
überschreibt.
OP #6051871
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.
OP #6051888
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.
#6052162
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.
OP #6052204
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren