2

私はC++でのプログラミングを始めたばかりです(IDEはCodeBlocksです)。

私は2つの簡単なクラス(SongとMetadata)を作成し、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;
}

添付のSongクラスとMetadataクラスをご覧ください。

このエラーにどう対応するかわかりません。

私の環境:-Windows 8、64ビット-コード::ブロック10.05-コンパイラ:GNUGCCコンパイラ

前もって感謝します!

セバスチャンのご挨拶

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;
}
4

1 に答える 1

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[]。これら2つを修正するだけではありません。それらすべてを修正します

覚えて。sizeof()渡されたフィールドのオクテットカウントを返します。つまり、char field[N];が返されNます。すでにC/C ++を知っている場合は、配列がゼロベースであり、したがってfield[N-1]最大許容インデックスであることを知っています。

于 2012-11-22T18:37:40.900 に答える