我尝试调整C代码来压缩来自D中http://sqlite.1065341.n5.nabble.com/Compress-function-tp11998p11999.html的数据而没有任何成功,这在运行时给了我Segmentation fault (core dumped)
。我已经尝试使用gdb进行调试,这似乎暗示了我对sqlite3_exec的调用有问题,这是我所知道的正确使用。
import etc.c.sqlite3, etc.c.zlib;
void main(){
sqlite3* db;
int rc;
char* errmsg;
rc = sqlite3_open(":memory:", &db);
rc = sqlite3_create_function(db, "compress", 1, SQLITE_UTF8, null,
&sqlite_compress, null, null);
rc = sqlite3_create_function(db, "decompress", 1, SQLITE_UTF8, null,
&sqlite_decompress, null, null);
rc = sqlite3_exec(db,
"select decompress(compress('may the force be with you'))="
"'may the force be with you'",
null, null, &errmsg);
assert(rc == SQLITE_OK);
sqlite3_close(db);
}
extern(C){
static void sqlite_compress(sqlite3_context *context, int argc, sqlite3_value **argv){
ulong rc, nIn, nOut;
const(ubyte)* inBuf;
ubyte* outBuf;
inBuf = cast(ubyte*)sqlite3_value_blob(argv[0]);
nIn = sqlite3_value_bytes(argv[0]);
nOut = 13 + nIn + (nIn+999)/1000;
outBuf = cast(ubyte*)sqlite3_malloc(cast(int)nOut+4);
outBuf[0] = nIn>>24 & 0xff;
outBuf[1] = nIn>>16 & 0xff;
outBuf[2] = nIn>>8 & 0xff;
outBuf[3] = nIn & 0xff;
rc = compress(&outBuf[4], &nOut, inBuf, nIn);
if( rc==Z_OK ){
sqlite3_result_blob(context, &outBuf, cast(int)nOut+4, &sqlite3_free);
}else{
sqlite3_free(&outBuf);
sqlite3_result_error(context, "uncompressable data", -1);
}
}
static void sqlite_decompress(sqlite3_context *context, int argc, sqlite3_value **argv){
ulong rc, nIn, nOut;
const(ubyte)* inBuf;
ubyte* outBuf;
nIn = sqlite3_value_bytes(argv[0]);
if( nIn<=4 )
return;
inBuf = cast(ubyte*)sqlite3_value_blob(argv[0]);
nOut = (inBuf[0]<<24) + (inBuf[1]<<16) + (inBuf[2]<<8) + inBuf[3];
outBuf = cast(ubyte*)sqlite3_malloc( cast(int)nOut+1 );
rc = uncompress(outBuf, &nOut, &inBuf[4], nIn);
if( rc==Z_OK ){
sqlite3_result_blob(context, outBuf, cast(int)nOut, &sqlite3_free);
}else{
sqlite3_free(&outBuf);
sqlite3_result_error(context, "data is not compressed", -1);
}
}
}
可能导致问题的原因以及如何解决?
答案 0 :(得分:3)
sqlite_compress
中的这一行是罪魁祸首:
sqlite3_result_blob(context, &outBuf, cast(int)nOut+4, &sqlite3_free);
这是sqlite_decompress
中的正确对应方:
sqlite3_result_blob(context, outBuf, cast(int)nOut, &sqlite3_free);
注意区别?在您sqlite_compress
传递&outBuf
时,outBuf
传递&outBuf
。使用sqlite3_free
时,outBuf
会尝试释放指向必须失败的局部变量jquery
的指针。