gpt4 book ai didi

c++ - CString 的动态 3 维数组中的内存泄漏

转载 作者:行者123 更新时间:2023-11-27 22:45:00 24 4
gpt4 key购买 nike

我正在使用 CString 类型的 3 维数组的动态声明。 (我知道,为什么又是 CString?使用 vector !我不能,赋值需要使用 cstring。)

所以任务是制作一个用户定义的歌曲播放列表,允许添加、删除、显示和搜索。此外,播放列表必须保存到名为 songs.txt 的文本文件中。

我的问题是我在我的添加函数中不断出现内存泄漏我将分享所有代码和内存泄漏错误,所以你可以看到。

Valgrind 错误:

==17401== HEAP SUMMARY:
==17401== in use at exit: 73,519 bytes in 31 blocks
==17401== total heap usage: 36 allocs, 5 frees, 91,199 bytes allocated
==17401==
==17401== 1 bytes in 1 blocks are definitely lost in loss record 1 of 12
==17401== at 0x4C284B7: operator new[](unsigned long) (in
/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==17401== by 0x401BB3: songlist::readList(std::basic_ifstream<char,
std::char_traits<char> >&)

其余的只是通过 12 中的 12 来重复自己

我的代码:

defs.cpp:

#includes <iostream>
#include <cstring>
#include <iomanip>
#include <fstream>
#include "proj4.h"

using namespace std;

void songlist::makeList()
{
MAX_TRAX = 0;
song = new char**[20];
for (int i=0; i<20; i++)
{
song[i] = new char*[5];
}
}

void songlist::readList(ifstream& infile)
{
int counter = 0;
if (!infile.is_open())
{
cout << "Cannot open file: songs.txt";
}

while(!infile.eof())
{
infile >> newSong.title >> newSong.artist >>
newSong.durationMin >> newSong.durationSec >> newSong.album;

int i = strlen(newSong.title);
i++;
int j = strlen(newSong.artist);
j++;
int k = strlen(newSong.durationMin);
k++;
int l = strlen(newSong.durationSec);
l++;
int m = strlen(newSong.album);
m++;

if(i>0)
{

song[counter][0]= new char[i];
song[counter][1]= new char[j];
song[counter][2]= new char[k];
song[counter][3]= new char[l];
song[counter][4]= new char[m];

song[counter][0] = newSong.title;
song[counter][1] = newSong.artist;
song[counter][2] = newSong.durationMin;
song[counter][3] = newSong.durationSec;
song[counter][4] = newSong.album;
counter++;
}
MAX_TRAX = counter-1;
}

counter = 0;

}

void songlist::saveList(ofstream& outfile)
{
if (!outfile.is_open())
{
cout << "Cannot find file: songs.txt";
}

for (int i=0; i<=MAX_TRAX; i++)
{
outfile << song[i][0] << "; " << song[i][1] << "; " << song[i]
[2] << "; " <<song[i][3] << "; " << song[i][4] << ";" << endl;
}
}

void songlist::displayList()const
{
cout << left << setw(16) << '#' << left << setw(30) << "Song Name" <<
left << setw(22) << "Artist Name" << left << setw(17) << "Duration" <<
left << setw(20) << "Album Title" << endl;
cout << left << setw(110) << setfill ('-') << '-' << endl;
cout << setfill (' ');

if (strlen(newSong.title)>=1)
{
for (int i=0; i<=MAX_TRAX; i++)
{
cout << left << setw(4) << i+1 << left << setw(31) <<
song[i][0] << left << setw(31) << song[i][1] << right << setw(4) << song[i]
[2]
<< ':';
if (strlen(song[i][3])==1)
{
cout << '0';
cout << left << setw(3) << song[i][3] <<
left << setw(3) << song[i][4] << endl;
}
else
cout << left << setw(4) << song[i][3] << left <<
setw(3) << song[i][4] << endl;
}
cout << left << setw(110) << setfill ('-') << '-' << endl;
cout << setfill (' ');
}
}

void songlist::addSong()
{
if(strlen(newSong.title)>=1)
{
MAX_TRAX++;
}

cout << "Add a Song" << endl;
cout << endl;

cout << "Enter Song Title: ";
cin.ignore();
cin.get(newSong.title, 30);
cout << endl;

cout << "Enter Artist Name: ";
cin.ignore();
cin.get(newSong.artist, 30);
cout << endl;

cout << "Enter Track Duration";
cout << endl;
cout << "Minutes: ";
cin.ignore();
cin.get(newSong.durationMin, 3);
cout << endl;


cout << "Seconds: ";
cin.ignore();
cin.get(newSong.durationSec, 3);
cout << endl;

cout << "Enter Album Title: ";
cin.ignore();
cin.get(newSong.album, 30);
cout << endl;
cout << "Song Added to Database!";
cout << endl;
cout << endl;

int i = strlen(newSong.title);
i++;
int j = strlen(newSong.artist);
j++;
int k = strlen(newSong.durationMin);
k++;
int l = strlen(newSong.durationSec);
l++;
int m = strlen(newSong.album);
m++;

song[MAX_TRAX][0]= new char[i];
song[MAX_TRAX][1]= new char[j];
song[MAX_TRAX][2]= new char[k];
song[MAX_TRAX][3]= new char[l];
song[MAX_TRAX][4]= new char[m];

song[MAX_TRAX][0] = newSong.title;
song[MAX_TRAX][1] = newSong.artist;
song[MAX_TRAX][2] = newSong.durationMin;
song[MAX_TRAX][3] = newSong.durationSec;
song[MAX_TRAX][4] = newSong.album;

}
void songlist::removeSong()
{
int p = 0;
int q = 0;
int n = 0;
cout << "Remove a Song" << endl;
cout << "Enter Track Number to Confirm Deletion: ";
cin >> n;
cout << endl;

while (!(n >=1 && n <= MAX_TRAX+1))
{
cin.clear();
cin.ignore();
cout << "Must be a number between 1 and " << MAX_TRAX+1 << endl;
cout << "Enter Track Number to Confirm Deletion: ";
cin >> n;
cout << endl;
}
n--;
for (p=n;p<MAX_TRAX; p++)
{
for(q=0;q<5;q++)
{
delete[] song[p][q];
}

int i = strlen(song[p+1][0]);
i++;
int j = strlen(song[p+1][1]);
j++;
int k = strlen(song[p+1][2]);
k++;
int l = strlen(song[p+1][3]);
l++;
int m = strlen(song[p+1][4]);
m++;

song[p][0] = new char[i];
song[p][1] = new char[j];
song[p][2] = new char[k];
song[p][3] = new char[l];
song[p][4] = new char[m];

song[p][0] = song[p+1][0];
song[p][1] = song[p+1][0];
song[p][2] = song[p+1][0];
song[p][3] = song[p+1][0];
song[p][4] = song[p+1][0];
}

MAX_TRAX--;
n++;
cout << "Track Number " << n << " Deleted" << endl;
}

void songlist::searchList()const
{
int i;
char aOrB;
int counter = 0;
char art[30];
char alb[30];

cout << "Search by (a)rtist or al(b)um? (a or b): ";
cin >> aOrB;
cout << endl;

if (aOrB != 'a' && aOrB != 'b')
{
cout << "(a or b): ";
cin >> aOrB;
cout << endl;
}

if (aOrB == 'a')
{
cout << "Artist Name: ";
cin.ignore();
cin.get(art, 30);

for(i=0; i<=(MAX_TRAX); i++)
{
if (strcmp(art, song[i][1])==0)
{
cout << left << setw(2) << i+1 << left <<
setw(32) << song[i][0] << left << setw(32) << song[i][1] << right << setw(4)
<< song[i][2] << ':' << left << setw(5) << song[i][3] << left << setw(32) <<
song[i][4] << endl;
counter++;
}
}
}

else
{
cout << "Album Name: ";
cin.ignore();
cin.get(alb, 30);

for(i=0; i<=(MAX_TRAX); i++)
{
if (strcmp(alb, song[i][4])==0)
{
cout << left << setw(2) << i+1 << left <<
setw(32) << song[i][0] << left << setw(32) << song[i][1] << right << setw(4)
<<
song[i][2] << ':' << left << setw(5) << song[i][3] << left << setw(32) <<
song[i][4] << endl;
counter++;
}
}
}

if (!counter)
{
cout << endl;
cout << "No Matches Found; check spelling and/or case." << endl;
}
}

void songlist::deleteAll()
{
for(int i=0; i>=20; i++)
{
for (int j=0; j<5; j++)
delete[] song[i][j];
delete[] song[i];
}
delete[] song;
}

songlist::songlist()
{
}

Proj4.h:

#ifndef PROJ3_H
#define PROJ3_H
#include <iostream>
#include <fstream>
#include <cstring>
#include <iomanip>

using namespace std;

class songlist
{
public:
void readList(ifstream& infile);
void saveList(ofstream& outfile);
void displayList() const;
void makeList();
void addSong();
void removeSong();
void searchList() const;
void deleteAll();
songlist();
private:
struct songs
{
char title[30] = {'\0'};
char artist[30] = {'\0'};
int intMin = 0;
int intSec = 0;
char durationMin[3] = {'\0'};
char durationSec[3] = {'\0'};
char album[30] = {'\0'};
};
songs newSong;

int MAX_TRAX;

char *** song;
};
#endif

应用程序.cpp:

#include <iostream>
#include <cstring>
#include <iomanip>
#include <fstream>
#include "proj4.h"

using namespace std;

int main()
{
char selection;

cout << endl;
cout << "*Music Track Database*" << endl;

ifstream infile;
ofstream outfile;
infile.open("songs.txt");
outfile.open("songs.txt");
songlist newlist;
newlist.makeList();

do
{
cout << endl;
cout << "Main Menu:" << endl;
cout << endl;
cout << "(a)dd a song" << endl;
cout << "(r)emove a song" << endl;
cout << "(d)isplay track listings" << endl;
cout << "(s)earch for a track" << endl;
cout << "(q)uit" << endl;
cout << endl;
cout << "Select (a, r, d, s, q): ";
cin >> selection;
cout << endl;

if (selection != 'a' && selection != 'r' && selection != 'd'
&& selection != 's' && selection != 'q')
{
cout << "Select (a, r, d, s, q): ";
cin >> selection;
cout << endl;
}

switch (selection)
{
case 'a':
newlist.readList(infile);
newlist.addSong();
newlist.saveList(outfile);
break;
case 'd':
newlist.readList(infile);
newlist.displayList();
break;
case 'r':
newlist.removeSong();
newlist.saveList(outfile);
break;
case 's':
newlist.readList(infile);
newlist.searchList();
break;
}
}while (selection != 'q');

newlist.deleteAll();

cout << "Happy Trails To You; Until We Meet Again!" << endl;
cout << endl;

infile.close();
outfile.close();

return 0;
}

这里还有一个简单的 makefile 来测试它:

all:
g++ app.cpp proj4.h defs.cpp -o proj4;
clean:
clean make;

任何帮助!提前谢谢你。

最佳答案

你甚至不能使用结构或类?当您成为三星级程序员时,通常情况会很糟糕。

你的分配差了一个(空终止...)

但真正的漏洞就在这里。想想这是做什么的:

song[p][0] = new char[i];
song[p][1] = new char[j];
song[p][2] = new char[k];
song[p][3] = new char[l];
song[p][4] = new char[m];

song[p][0] = song[p+1][0];
song[p][1] = song[p+1][0];
song[p][2] = song[p+1][0];
song[p][3] = song[p+1][0];
song[p][4] = song[p+1][0];

您首先分配内存,然后通过为这些指针分配其他内容来丢弃这些指针。您永远无法取回它们,这就是泄漏。

关于c++ - CString 的动态 3 维数组中的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44234348/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com