http://www.pronix.de -> Forum -> C-Programmieren

Unterseiten

Forum: C-Programmieren

Moderatoren: juergen, Martin Conrad

Thema: mysql_free_result

  • (nur registrierte Mitglieder)

mysql_free_result

Patrick am 29.07.2010 um 16:29

Ich möchte das Ergebnis einer Datenbankanfrage in einer Struktur sichern.
Anschließend wird der Speicher brav mit mysql_free_result freigeben.
Der printf-Aufruf im Quelltext vor mysql_free_result gibt das erwartete Ergebnis aus.
Der printf-Aufruf nach dem mysql_free_result sagt, dass der String zwei Byte länger ist und hängt ein lustiges Zeichen hinten dran.
Wo mache ich den Fehler?

struct
inbox
{
 char *UpdatedInDB;
 char *ReceivingDateTime;
 char *SenderNumber;
 char *TextDecoded;
 unsigned long  ID;
 char *RecipientID;
 unsigned long modem_id;
} typedef INBOX;



/*******************************************************************************
* Ermittelt einen Datensatz aus der Tabelle `inbox` anhand der uebergebenen
* Datensatz-Id.
*
* @param  DBO*   Struktur, welche einen Datenbank-Handler mitbringt.
* @return INBOX* Datensatz entsprechend der uebergebenen ID.
*******************************************************************************/
static
inline
INBOX *
getInboxById ( DBO *dbo,
          unsigned long id )
{
 if (NULL == dbo)
  die("getInboxById() dbo==NULL");

 char sql[1024], error[2048];
 sprintf(sql, "SELECT `inbox`.`UpdatedInDB`, `inbox`.`ReceivingDateTime`, "
              "`inbox`.`SenderNumber`, `inbox`.`TextDecoded`, "
              "`inbox`.`RecipientID`, `modems`.`id` "
              "FROM inbox "
              "LEFT JOIN modems ON inbox.RecipientID = modems.uid "
              "WHERE `inbox`.`Processed` = 'false' "
              "AND `inbox`.`ID` = %ld", id);

 if (0 != mysql_real_query(dbo->dbh, sql, strlen(sql)))
 {
  sprintf(error, "getInboxById(): %u (%s)\n", mysql_errno(dbo->dbh), mysql_error(dbo->dbh));
  die(error);
 }

 MYSQL_ROW row;
 MYSQL_RES *res     = mysql_store_result(dbo->dbh);
 unsigned long rows = (unsigned long) mysql_num_rows(res);

 if (1    != rows
  || NULL == (row=mysql_fetch_row(res)))
 {
  sprintf(error, "getInboxById() ergab %ld Treffer", rows);
  die(error);
 }

 INBOX *inbox = malloc(sizeof(INBOX));

 if (NULL == inbox
  || NULL == (inbox->UpdatedInDB       = malloc(strlen(row[0] +1)))
  || NULL == (inbox->ReceivingDateTime = malloc(strlen(row[1] +1)))
  || NULL == (inbox->SenderNumber      = malloc(strlen(row[2] +1)))
  || NULL == (inbox->TextDecoded       = malloc(strlen(row[3] +1)))
  || NULL == (inbox->RecipientID       = malloc(strlen(row[4] +1))))
 {
  die("getInboxById() Speicheranforderung fehlgeschlagen.");
 }

 // Strukturelemente mit 0 fuellen.
 // Zuvor wurde pro Element Speicher fuer das Attribut der Datenbank
 // plus ein Byte zum terminieren reserviert.
 memset(inbox->UpdatedInDB,       0, strlen(row[0])+1);
 memset(inbox->ReceivingDateTime, 0, strlen(row[1])+1);
 memset(inbox->SenderNumber,      0, strlen(row[2])+1);
 memset(inbox->TextDecoded,       0, strlen(row[3])+1);
 memset(inbox->RecipientID,       0, strlen(row[4])+1);


 // Garantiert lt. manpage korrekten Kopiervorgang.
 // Zeilenende ist bereits terminiert, weil Strukturelemente mit 0 gefuellt.
 memmove(inbox->UpdatedInDB,       row[0], strlen(row[0]));
 memmove(inbox->ReceivingDateTime, row[1], strlen(row[1]));
 memmove(inbox->SenderNumber,      row[2], strlen(row[2]));
 memmove(inbox->TextDecoded,       row[3], strlen(row[3]));
 memmove(inbox->RecipientID,       row[4], strlen(row[4]));
 inbox->ID       = id;
 inbox->modem_id = strtol(row[5], NULL, 10);


printf("inbox->RecipientID %s, size: %d\n", inbox->RecipientID, strlen(inbox->RecipientID));
//inbox->RecipientID 012345678900, size: 12

 mysql_free_result(res);

printf("inbox->RecipientID %s, size: %d\n", inbox->RecipientID, strlen(inbox->RecipientID));
//inbox->RecipientID 012345678900▒, size: 14
 return inbox;
}


TTY

$> gcc -v

Using built-in specs.

Target: i486-linux-gnu

Configured with: ../src/configure -v --with-pkgversion='Debian 4.3.2-1.1' --with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-targets=all --enable-cld --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu

Thread model: posix

gcc version 4.3.2 (Debian 4.3.2-1.1)



Gruß,
Patrick-Oliver

Nachtrag:
//inbox->RecipientID 012345678900▒, size: 14
Das 'lustige Zeichen' wird vom CMS in &9618; umgewandelt.
Laut http://de.wikipedia.org/wiki/Unicode-Block_Blockelemente ein Medium Shape.

--
To follow the path: look to the master, follow the master, walk with the master, see through the master, become the master.

 

Re: mysql_free_result

Patrick am 29.07.2010 um 16:40

Btw. memcpy und strncpy habe ich ebenfalls getestet.
Auch habe ich die Strings von Hand nach dem kopieren terminiert.
Alles ohne den gewünschten Erfolg.

Gelöst habe ich es vorerst, indem mysql_free_result direkt nach dem mysql_fetch_row aufrufe.
 if (1 != rows
  || NULL == (row=mysql_fetch_row(res)))
 {
  sprintf(error, "getInboxById() ergab %ld Treffer", rows);
  die(error);
 }

 mysql_free_result(res);


Verstehen tue ich das aber nicht Grafik: Smilie Lachend

--
To follow the path: look to the master, follow the master, walk with the master, see through the master, become the master.

 

Re: mysql_free_result

Patrick am 03.08.2010 um 11:50

 sprintf(sql, "SELECT `inbox`.`UpdatedInDB`, `inbox`.`ReceivingDateTime`, "
              "`inbox`.`SenderNumber`, `inbox`.`TextDecoded`, "
              "`inbox`.`RecipientID`, `inbox`.`Processed`, `modems`.`id` "
              "FROM inbox "
              "LEFT JOIN modems ON inbox.RecipientID = modems.uid "
              "WHERE `inbox`.`ID` = '%ld'", id);


Mein Fehler war, dass ich den Wert für inbox.ID nicht in Anführungszeichen gesetzt habe.
Als ich die Funktion heute mit dem Wert 31 aufgerufen habe, hat sich mein Programm mit einer Segmentation-Fault verabschiedet.
Laut ASCII-Tabelle ist 32 ein Unit-Seperator, was wohl so nicht am Ende einer Zeichenkette stehen darf.

--
To follow the path: look to the master, follow the master, walk with the master, see through the master, become the master.

 
  • (nur registrierte Mitglieder)