Недостаточно памяти при использовании sqlite3

Я только начинаю с программирования на C ++ (IDE это CodeBlocks).

Я написал два простых класса (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;
}

Пожалуйста, смотрите прилагаемые классы Песни и Метаданных.

Я не знаю, как реагировать на эту ошибку.

Моя среда:
— Windows 8, 64 бит
— Код :: Блоки 10.05
— Компилятор: GNU GCC Compiler

Заранее спасибо!

Привет
Себастьян

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

2

Решение

Для начинающих: Все Ваш код завершения строки неверен в 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] это максимально допустимый индекс.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector