c++ - 使用sqlite3时内存不足

标签 c++ sqlite out-of-memory

<分区>

我刚开始用 C++ 编程(IDE 是 CodeBlocks)。

我编写了两个简单的类(歌曲和元数据)并使用 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 位 - 代码:: block 10.05 - 编译器:GNU GCC 编译器

提前致谢!

问候语 塞巴斯蒂安

歌曲.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();

};

歌曲.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;
}

元数据.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

元数据.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;
}

最佳答案

对于初学者:所有您的字符串终止代码在 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] 是允许的最大索引。

关于c++ - 使用sqlite3时内存不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13518218/

相关文章:

c# - byte[] 并有效地通过引用传递

c++ - C++ 是否仍积极用于通用开发?

c++ - 没有参数的构造函数不起作用,但有参数的构造函数起作用

php - 使用 PHP PDO 在 sqlite 中启用共享寻呼机缓存

java - 获取 Java OutOfMemoryError : Java heap space error that I can't debug

python - python 中使用 numpy.pad 函数出现内存错误

c++ - 避免循环的 timeGetTime 的最佳替代品是什么?

c++ - 使用 for_each 函数显示每个容器元素

ios - 如何使用 swift 在 iOS coredata sqlite 中启用删除模式

linux - 测量 sqlite 数据库的负载