473,400 Members | 2,145 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,400 software developers and data experts.

(part 20) Han from China answers your C questions

SQLITE Blob writing error

wizard said:
database.
I've a problem to read from blob struct called 'Points'
Any help would be appreciated
Yeah, no problem. We love SQLITE around here.
Reagards
Greg

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "sqlite3.h"
You may need to include the header for unlink(). On a POSIX system,
this would be unistd.h.
typedef unsigned char uchar;

char dbname[1000];
static sqlite3 *db1;

void
exec_simple (char *stm)
{
int rc;
char *errMsg = 0;

rc = sqlite3_exec (db1, stm, NULL, 0, &errMsg);
if (rc != SQLITE_OK)
{
fprintf (stderr, "SQL error: %s\n", errMsg);
}

}

typedef struct points
{
long numPoints;
double *x;

}Points;

int
main (int argc, char **argv)
{
char *errMsg = 0;
int rc;
sqlite3_stmt *stmt = NULL;
Points *pointsP;
long numPoints;
long size;
int iii;
char text[32];
uchar *pabyRec;
int nRecordSize;
int num_punkt;
int nOffset;

strcpy(dbname,".\\test.db");

unlink (dbname);

rc = sqlite3_open (dbname, &db1);

if (rc)
{
fprintf (stderr, "Can't open database: %s\n", sqlite3_errmsg (db1));
exit (1);
}

exec_simple ("PRAGMA page_size=8192");
exec_simple ("PRAGMA synchronous = OFF");
exec_simple ("PRAGMA count_changes = OFF");
exec_simple ("PRAGMA temp_store = MEMORY");

exec_simple ("CREATE TABLE punkty(id INTEGER PRIMARY KEY, value BLOB)");

// write record

numPoints=5;

size = numPoints * 1 * sizeof(double) + sizeof(int);
I think you want sizeof(long).
pointsP = (Points *) malloc(size);
Casting the return from malloc() is optional. Also, you are allocating more
memory than is indicated by the declaration of the Points structure. This
appears to be intentional, but I would advise you to seek a much cleaner
solution.

FYI: Only the address returned by malloc() is suitably aligned for
any data type you need. I predict that at some point (not in the code
you've posted so far) you will assume that malloc_address + sizeof(long)
is suitably aligned for a double type. This results in undefined behavior.
memcpy( pointsP, &numPoints, sizeof(int));
If you really must do this, change it to

memcpy(..., sizeof(long));

Otherwise, simply do

pointsP->numPoints = numPoints;

The address of the first structure member, pointsP->numPoints,
should be equal to pointsP.
nRecordSize = 4;
Size assumption of sizeof(long) = 4.
>
pointsP->x = (double *) calloc(numPoints, sizeof(double));
Cast is again optional.
for( iii = 0; iii < numPoints; iii++ )
{
pointsP->x[iii] = (double)iii*100+0.01;
}
This appears correct.
for( iii = 0; iii < numPoints; iii++ )
{
memcpy( pointsP + nRecordSize, pointsP->x + iii, sizeof(double));
The behavior you probably wanted would be achieved by

memcpy((char *)pointsP + nRecordSize, ...);

since pointsP + nRecordSize = (char *)pointsP + nRecordSize*sizeof(Points)

However, "fixing" the code would, subject to internal structure padding,
trash pointsP->x.

You have conflicting data structures. On the one hand, you have a structure
that, ignoring internal padding, looks like this in memory:

pointsP
------------ <--/
| long |
------------ --------------------------
| double * | ----|double|double|...|double|
------------ --------------------------

Then you've gone ahead and modified the above to this:
pointsP
--------------- <--/
| int / long |
---------------
| double |
---------------
| double |
---------------
| ... |
---------------
| double |
---------------

Yet you still expect that double pointer to be there. What's
there instead is a junk pointer that is causing you to read
doubles from some other place in memory.
nRecordSize += 1 * 8;
Size assumption of sizeof(double) = 8.
}

rc = sqlite3_prepare(db1, "insert into punkty values (1,?);", -1, &stmt,
NULL);

if (rc)
{
fprintf (stderr, "ERORR: %s\n", sqlite3_errmsg (db1));
exit (1);
}

rc =sqlite3_bind_blob(stmt, 1, pointsP, size, NULL);
if (rc)
{
fprintf (stderr, "ERORR: %s\n", sqlite3_errmsg (db1));
exit (1);
}

sqlite3_step(stmt);

rc =sqlite3_finalize(stmt);
if (rc)
{
fprintf (stderr, "ERORR: %s\n", sqlite3_errmsg (db1));
exit (1);
}

if( pointsP->x != NULL )
{
free( pointsP->x );
pointsP->x=NULL;
}

free(pointsP);
pointsP=NULL;

// read record
rc = sqlite3_prepare (db1, "select *from punkty", -1, &stmt, NULL);

if (rc != SQLITE_OK)
{
fprintf (stderr, " %s\n", sqlite3_errmsg (db1));
}

while (sqlite3_step (stmt) == SQLITE_ROW)
{

if (rc != SQLITE_OK)
{
fprintf (stderr, "SQL error: %s\n", errMsg);
}

size = sqlite3_column_bytes(stmt, 1);

pointsP= (Points *)malloc(size);
Cast is optional.
>
memcpy(pointsP,sqlite3_column_blob(stmt, 1),size);
Probably not a good thing.
printf("size=%ld\n",size);

memcpy( &num_punkt, pointsP, 4 );
What you want is

num_punkt = pointsP->numPoints;

Note also that num_punkt is an int, whereas pointsP->numPoints
is a long.
printf("pointsP->numPoints=%ld\n",num_punkt);

nOffset = 4;
Another size assumption.
>
pointsP->x = (double *) calloc(num_punkt, sizeof(double));
Cast is optional.
>
for( iii = 0; iii < num_punkt; iii++ )
{
memcpy(pointsP->x + iii, pointsP + nOffset + iii * 8, 8); //maybe here
is a fault
}
Yes, see the above data structure diagrams. This time you appear to have
trashed in reverse.
>
for(iii=0;iii<num_punkt;iii++)
{
printf("x=%.2f\n",pointsP->x[iii]); // here prints rubbish
}

printf("ID=%ld\n", sqlite3_column_int(stmt,0));

}
sqlite3_finalize (stmt);
}
I'm not sure whether I have read your code correctly. A lot of
people here have killfiled me, so don't take no replies to my
post to be an indication of the correctness of my post. Read
over what I've said, and see whether it makes sense.
Yours,
Han from China

















Nov 14 '08 #1
0 1191

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Nomen Nescio | last post by:
A new learner's question Flash Gordon wrote: To the OP, please be aware that Flash Gordon has a history of either deliberately misleading and "miss-informing" posters to this newsgroup or...
0
by: Nomen Nescio | last post by:
what is the type for this call? Neo said: Neo, buddy, I've decided to give you a little summary for reference so that you don't have to sift through excess verbiage, cryptic meanderings,...
1
by: George Orwell | last post by:
its urgent.pls help me. mona said: mona said: Hey again, mona. Please check the thread "(part 21) Han from China answers your C questions", in which I gave you a program with
16
by: Borked Pseudo Mailed | last post by:
Error handling in C Nick Keighley said: ... ... To the OP, please be aware that Nick Keighley is a known troll and is deliberately providing you with unsound advice. You asked for error...
1
by: George Orwell | last post by:
File Seeking / Overwriting bytes Martien Verbruggen said: And this is, of course, also not right. fseek() does support SEEK_END on text streams. If you want to know why, please start a...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.