2012-11-22 39 views
2

我剛剛開始用C++編程(IDE是CodeBlocks)。使用sqlite3時內存不足

我寫了兩個簡單的類(宋和元數據)和用sqlite測試。

問題:我的程序似乎沒有足夠的內存:當我啓動程序時,它立即崩潰或sqlite3_open命令返回錯誤「內存不足」。當我測試沒有任何其他代碼的SQLITE函數時,它的工作原理!

所以這不起作用:

#include <iostream> 
#include "metadata.h" 
#include "Song.h" 
#include <cstdio> 
#include "sqlite3.h" 

using namespace std; 

int main() 
{ 
    // Without this block it DOES work! 
    Metadata* tmpMeta = new Metadata("Eiffel 65", "Blue", "Europop"); 
    Song* tmpSong; 
    tmpSong = new Song(); 
    tmpSong->set_metadata(*tmpMeta); 
    // end of block 

    sqlite3 *db; 
    int rc; 
    rc = sqlite3_open_v2("test.db", &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); 
    cout << "Result: " << sqlite3_errmsg(db) << '\n'; 
    sqlite3_close(db); 
    return 0; 
} 

請看附件宋,元數據類。

我不知道如何應對這個錯誤。

我的環境: - Windows 8中,64位 - 代碼:: Blocks的10.05 - 編譯器:GNU GCC編譯器

預先感謝您!

問候 塞巴斯蒂安

Song.h:

#include <iostream> 
#include <cstring> 
#include "metadata.h" 

using namespace std; 

class Song { 
    private: 
    Metadata metadata; 
    unsigned int iD; 
    char filename[400]; 

    public: 
    //Constructors 
    Song(Metadata, unsigned int, const char*); 
    Song(); 

    //Methods 
    void set_metadata(Metadata& meta); 
    void set_id(unsigned int i); 
    void set_filename(const char* f); 

    Metadata get_metadata(); 
    unsigned int get_id(); 
    const char* get_filename(); 

}; 

Song.cpp:

#include <iostream> 
#include "Song.h" 

using namespace std; 

Song::Song(Metadata m, unsigned int id, const char* f) { 
    metadata = m; 
    iD = id; 
    strncpy(filename, f, sizeof(filename)-1); 
    filename[sizeof(filename)] = '\0'; 
} 

Song::Song() { 
    Metadata tmpMeta; 
    metadata = tmpMeta; 

    iD = 0; 
    strncpy(filename, "unknown", sizeof(filename) -1); 
    filename[sizeof(filename)] = '\0'; 
} 

void Song::set_filename(const char* f) { 
    strncpy(filename, f, sizeof(filename)-1); 
    filename[sizeof(filename)] = '\0'; 
} 

void Song::set_id(unsigned int i) { 
    iD = i; 
} 

void Song::set_metadata(Metadata& meta) { 
    metadata = meta; 
} 

Metadata Song::get_metadata() { 
    return metadata; 
} 

const char* Song::get_filename() { 
    return filename; 
} 

unsigned int Song::get_id() { 
    return iD; 
} 

Metadata.h:

#include <iostream> 
#include <cstring> 
#ifndef _METADATA_H_ 
#define _METADATA_H_ 

using namespace std; 
class Metadata { 
    private: 
    unsigned int trackNumber; 
    char artist[20]; 
    char title[20]; 
    unsigned int year; 
    char genre[20]; 
    char album[20]; 

    public: 
    Metadata(const char*, const char*, const char*); 

    const char* get_artist(); 
    const char* get_title(); 
    const char* get_album(); 
    const char* get_genre(); 
    unsigned int get_trackNumber(); 
    unsigned int get_year(); 

    void set_artist(const char*); 
    void set_title(const char*); 
    void set_album(const char*); 
    void set_genre(const char*); 
    void set_year(unsigned int); 
    void set_trackNumber(unsigned int); 
}; 

#endif 

Metadata.cpp:

#include <iostream> 
#include "metadata.h" 

Metadata::Metadata(const char* ar, const char* tit, const char* al) { 
    trackNumber = 0; 
    year = 0; 
    strncpy(genre, "unknown", sizeof(genre) -1); 
    genre[sizeof(genre)] = '\0'; 

    strncpy(artist, ar, sizeof(artist) -1); 
    artist[sizeof(artist)] = '\0'; 

    strncpy(title, tit, sizeof(title) -1); 
    title[sizeof(title)] = '\0'; 

    strncpy(album, al, sizeof(album) -1); 
    album[sizeof(album)] = '\0'; 
} 

const char* Metadata::get_artist() { 
    return artist; 
} 

const char* Metadata::get_title() { 
    return title; 
} 

const char* Metadata::get_album() { 
    return album; 
} 

const char* Metadata::get_genre() { 
    return genre; 
} 

void Metadata::set_artist(const char* ar) { 
    strncpy(artist, ar, sizeof(artist) -1); 
    artist[sizeof(artist)] = '\0'; 
} 

void Metadata::set_title(const char* tit) { 
    strncpy(title, tit, sizeof(title) -1); 
    title[sizeof(title)] = '\0'; 
} 

void Metadata::set_album(const char* al) { 
    strncpy(album, al, sizeof(album) -1); 
    album[sizeof(album)] = '\0'; 
} 

void Metadata::set_genre(const char* g) { 
    strncpy(genre, g, sizeof(genre) -1); 
    genre[sizeof(genre)] = '\0'; 
} 

void Metadata::set_trackNumber(unsigned int tn) { 
    trackNumber = tn; 
} 

void Metadata::set_year(unsigned int y) { 
    year = y; 
} 
+0

「當我測試沒有任何其他代碼的SQLITE函數時,它可以工作!」 - 這意味着它不是SQLITE,而是你的代碼。測試你的代碼沒有SQLITE的東西,並注意發生了什麼。 – Chad

+0

沒有SQLITE-Part也可以使用!沒有錯誤,只是當一起使用.... – SebBau

回答

1

對於初學者:所有您的字符串終止代碼是錯誤的Metadata.cpp和Song.cpp:

例子:

strncpy(genre, "unknown", sizeof(genre) -1); 
genre[sizeof(genre)] = '\0'; 

的調用函數strncpy()是正確。硬終結者不是。它應該是:

strncpy(genre, "unknown", sizeof(genre) -1); 
genre[sizeof(genre) -1] = '\0'; 

這會複製到所有字符串中。重新檢查他們。它會表現出一些副作用,直到你修復它們。考慮到這些對象都是堆分配的,所以你在不正確地終止Song::filename[]MetaData::albumin[]時會損壞你的堆。不要只修復這兩個; 修復它們全部

請記住。 sizeof()返回傳遞字段的八位字節數。這意味着char field[N];將返回N。如果你已經知道C/C++,你知道數組是基於零的,因此field[N-1]是最大允許的索引。

+0

非常感謝!我修復了你提到的部分。現在該程序按預期工作:) – SebBau