delete[] array caused a breakpoint - c++

I am trying to move a part of my code from main function to the additional void function, but I keep getting a problem with deleting allocated memory in the end. By that moment my program did not printed out my array as it should have. So i am looking for a tip how i can fix this.
#include "pch.h"
#include <iostream>
using namespace std;
void push(char* C, int size, istream &in);
void print_str(char* word, int length);
int main()
{
char* C = new char[0];
int size = 0;
cout << "input your text: ";
push(C, size, cin);
print_str(C, size);
delete[] C;
return 0;
};
void print_str(char* word, int length) {
for (int k = 0; k < length; k++)
{
cout << word[k];
}
cout << " ";
};
void push(char* C, int size, istream& in) {
while (1) {
char current = in.get();
if (current == '\n')
break;
else {
char* text1 = new char[size];
for (int i = 0; i < size; i++)
text1[i] = C[i];
delete[] C;
C = new char[size + 1];
for (int i = 0; i < size; i++)
C[i + 1] = text1[i];
delete[] text1;
C[0] = current;
}
size++;
}
}
Breakpoint

push changes the value of C, so it must return the new value so that the other code can see the change. Like this (for instance)
int main() {
...
C = push(C, size, cin);
...
}
char* push(char* C, int size, istream& in) {
while (1) {
char current = in.get();
if (current == '\n')
break;
else {
char* text1 = new char[size];
for (int i = 0; i < size; i++)
text1[i] = C[i];
delete[] C;
C = new char[size + 1];
for (int i = 0; i < size; i++)
C[i + 1] = text1[i];
delete[] text1;
C[0] = current;
}
size++;
}
return C;
}

you need to define c as pointer to pointer , because changing c in push scope won't change value of c in main
here's the changed code
#include "pch.h"
#include <iostream>
using namespace std;
void push(char** C, int size, istream& in);
void print_str(char* word, int length);
int main()
{
char* C = new char[0];
int size = 0;
cout << "input your text: ";
push(&C, size, cin);
print_str(C, size);
delete[] C;
return 0;
};
void print_str(char* word, int length) {
for (int k = 0; k < length; k++)
{
cout << word[k];
}
cout << " ";
};
void push(char** C, int size, istream& in) {
while (1) {
char current = in.get();
if (current == '\n')
break;
else {
char* text1 = new char[size];
for (int i = 0; i < size; i++)
text1[i] = (*C)[i];
delete[] C;
*C = new char[size + 1];
for (int i = 0; i < size; i++)
C[i + 1] = text1[i];
delete[] text1;
(*C)[0] = current;
}
size++;
}
}
also you can make more efficient algorithms to reach your end ,instead of allocating and deallocating memory for each character witch is costy

Related

C/C++ Remove Item From Struct Array

struct Student
{
char* name;
int balls;
};
void inputdata(Student **s, int *n)
{
int nn;
printf("%s\n", "Input amount of students");
scanf("%i", &nn);
Student* a = new Student[nn];
for (int i = 0; i < nn; ++i)
{
a[i].name = new char[4096];
scanf("%4095s", a[i].name);
scanf("%i", &a[i].balls);
}
*n = nn;
*s = a;
}
void print(Student *s, int n)
{
for (int i = 0; i < n; ++i)
{
printf("%s %i\n", s[i].name, s[i].balls);
}
}
void fixdata(Student *s, int *n)
{
int nn = *n;
for (int i = 0; i < nn; ++i)
{
if (s[i].balls > 100)
s[i].balls = 100;
else if (s[i].balls < 20)
{
for(int j = i; j < nn; ++j)
s[j] = s[j+1];
nn-=1;
}
}
*n = nn;
}
int main(int argc, char const *argv[])
{
Student* s;
int n;
inputdata(&s, &n);
print(s, n);
fixdata(s, &n);
print(s, n);
return 0;
}
I am trying to delete items where balls is less than 20. If so, I am supposed to shift items to the right, but at the same time remove items that are less than 20. I try, but it drastically shifts left 2 of the same records and is not doing the job properly.
UPDATE: Ok, I cleaned up the code a bit, now n decreases, but the problem when it stays at 1 record, that is supposed to be deleted too. I wonder why it does not get removed. Thankfully most of the trouble is fixed. Still, what is the problem deleting one item left when it is less than 20?
The function has a bug because after moving elements of a sub-array to the left in the next iteration of the for loop you will deal with another element instead of the required. Also the function should return the number of actual elements after removing some elements.
Also the function can produce memory leaks then one element of the array is assigned to other element of the array.
The function can look the following way
int fixdata( Student *s, int n )
{
int i = 0;
for ( int j = 0; j < n; ++j )
{
if ( not ( s[j].balls < 20 ) )
{
if ( i != j )
{
delete [] s[i].name;
s[i] = s[j];
s[j].name = nullptr;
}
if ( s[i].balls > 100 ) s[i].balls = 100;
++i;
}
}
return i;
}
And in main you can write
int m = fixdata(s, n);
print(s, m);
Also you should delete the allocated memory when the array is not needed any more.
for ( int i = 0; i < n; i++ )
{
delete [] s[i].name;
}
delete [] s;
In fixdata(), when "removing" an item, you are leaking that item's name, but more importantly your inner loop goes out of bounds of the array if the "last" item is removed.
Try this instead:
void fixdata(Student *s, int *n)
{
int nn = *n;
for (int i = 0; i < nn; ++i)
{
if (s[i].balls > 100)
{
s[i].balls = 100;
}
else if (s[i].balls < 20)
{
for(int j = i + 1; j < nn; ++j)
{
delete[] s[j-1].name;
s[j-1] = s[j];
s[j] = Student{};
}
--nn;
}
}
*n = nn;
}
That being said, your code is more C than C++. The C++ approach would be to use things like std::cin, std::string, and std::vector instead, eg:
#include <iostream>
#include <vector>
#include <string>
struct Student
{
std::string name;
int balls;
};
std::istream& operator>>(std::istream &in, Student &stud)
{
in >> s.name >> s.balls;
return in;
}
std::ostream& operator<<(std::ostream &out, const Student &stud)
{
out << stud.name << " " << stud.balls;
return out;
}
void inputdata(std:vector<Student> &s)
{
int nn;
std::cout << "Input amount of students\n";
std::cin >> nn;
std::vector<Student> a(nn);
for (auto &stud : s) {
std::cin >> stud;
}
s = std:move(a);
}
void print(const std::vector<Student> &s)
{
for (const auto &stud : s) {
std::cout << stud << "\n";
}
}
void fixdata(std::vector<Student> &s)
{
for (size_t i = 0; i < s.size();)
{
auto &stud = s[i];
if (stud.balls < 20) {
s.erase(s.begin()+i);
}
else {
if (stud.balls > 100) {
stud.balls = 100;
}
++i;
}
}
/* alternatively:
s.erase(
std::remove_if(s.begin(), s.end(),
[](const auto &stud){ return (stud.balls < 20); }
),
s.end()
);
std::for_each(s.begin(), s.end(),
[](auto &stud){ stud.balls = std::min(stud.balls, 100); }
);
*/
}
int main()
{
std::vector<Student> s;
inputdata(s);
print(s);
fixdata(s);
print(s);
return 0;
}

can't figure out where the heap overwriting is

#include<iostream>
using namespace std;
class Text{
public:
~Text(){
delete data;
}
char* data{};
int mSize{};
void fill(char* stringInput) {
mSize = strlen(stringInput);
data = new char [mSize];
for (int i = 0; i < mSize; i++){
data[i] = stringInput[i];
}
}
};
class myString{
public:
explicit myString(int size){ // constructor
strAmount = size;
strings = new Text [size];
}
~myString(){ // destructor
delete[] strings;
}
void addString(char* input){
strings[filledAmount].fill(input);
filledAmount++;
}
void delString(int pos){
for ( int i = pos; i < filledAmount; i++){
swap(strings[i], strings[i+1]);
}
strings[filledAmount].data = nullptr;
strings[filledAmount].mSize = 0;
filledAmount--;
}
void eraseEverything(){
for ( int i = 0; i < filledAmount; i++){
strings[i].data = {};
strings[i].mSize = 0;
}
filledAmount = 0;
}
int maxString() const {
int index{};
for ( int i = 0 ; i < filledAmount; i++){
if (strings[i].mSize > strings[index].mSize){
index = i;
}
}
return index;
}
int charAmount(){
int counter{};
for(int i = 0 ; i < filledAmount; i++){
counter+=strings[i].mSize;
}
return counter;
}
double digitPercentage(){
int digitsAmount{};
for(int i = 0; i < filledAmount; i++){
for ( int j = 0; j < strings[i].mSize; j++){
if (isdigit(strings[i].data[j])){
digitsAmount++;
}
}
}
double digitPercent = (digitsAmount/(double)charAmount())*100;
return digitPercent;
}
int filledAmount{};
int strAmount{};
Text* strings;
};
void render_text(myString& obj) {
for (int k = 0; k < obj.filledAmount; k++) {
for (int i = 0; i < obj.strings[k].mSize; i++)
cout << obj.strings[k].data[i];
cout << endl;
}
cout << endl;
}
int main(){
myString a(5);
a.addString((char *) "zxc 1v1 forever shadow fiend");
a.addString((char *) "This is a string");
a.addString((char *) "12345");
a.addString((char *) "Hello");
a.addString((char *) "A1oha Dance");
render_text(a);
a.delString(1);
render_text(a);
int maxInd = a.maxString();
cout << "Max string :\n";
for (int i = 0; i < a.strings[maxInd].mSize; i++) {
cout << a.strings[maxInd].data[i];
}
cout << "\n\n";
}
Please help me find the crash point. I suppose it crashes in the destructor pole, but I still can't figure it out.
This is something like a self-written string class, the problem is that I can't find the place where the problems start.
I also have a thought that the destructor tries to delete too much memory from the heap so the compiler prevents it from doing that. Can I somehow change the size of the strings array?
I have fixed all your memory errors, with the help of address sanitizers
The main change here is:
Add copy constructors and copy assignment operators
Manually delete the last element in the function delString
Though that the code now works, it's not a true modern c++ style code. I highly recommend that your using std::string to replace your Text class. Use std::vector to replace the dynamic array. Then you will stay away from the pain of memory errors. The delString should be replaced with vector::erase,which is much neat than your hand write algorithm.
https://en.cppreference.com/w/cpp/string/basic_string
https://en.cppreference.com/w/cpp/container/vector
I strongly recommend rewriting the code with std::string and std::vector
#include <cstring>
#include <iostream>
using namespace std;
class Text {
public:
~Text() { delete[] data; }
char* data{};
int mSize{};
Text() = default;
Text(const Text& oth) {
mSize = oth.mSize;
data = new char[mSize];
std::copy(oth.data, oth.data + oth.mSize, data);
}
Text& operator=(const Text& oth) {
delete[] data;
mSize = oth.mSize;
data = new char[mSize];
std::copy(oth.data, oth.data + oth.mSize, data);
return *this;
}
void fill(char* stringInput) {
mSize = strlen(stringInput) + 1;
data = new char[mSize];
for (int i = 0; i < mSize; i++) {
data[i] = stringInput[i];
}
}
};
class myString {
public:
explicit myString(int size) { // constructor
strAmount = size;
strings = new Text[size];
}
myString(const myString& oth) {
strAmount = oth.strAmount;
strings = new Text[oth.strAmount];
for (size_t i = 0; i < strAmount; ++i) {
strings[i] = oth.strings[i];
}
}
myString& operator=(const myString& oth) {
delete[] strings;
strAmount = oth.strAmount;
strings = new Text[oth.strAmount];
for (size_t i = 0; i < strAmount; ++i) {
strings[i] = oth.strings[i];
}
return *this;
}
~myString() { // destructor
delete[] strings;
}
void addString(char* input) {
strings[filledAmount].fill(input);
filledAmount++;
}
void delString(int pos) {
for (int i = pos; i < filledAmount; i++) {
swap(strings[i], strings[i + 1]);
}
delete[] strings[filledAmount].data;
strings[filledAmount].data = nullptr;
strings[filledAmount].mSize = 0;
filledAmount--;
}
void eraseEverything() {
for (int i = 0; i < filledAmount; i++) {
strings[i].data = {};
strings[i].mSize = 0;
}
filledAmount = 0;
}
int maxString() const {
int index{};
for (int i = 0; i < filledAmount; i++) {
if (strings[i].mSize > strings[index].mSize) {
index = i;
}
}
return index;
}
int charAmount() {
int counter{};
for (int i = 0; i < filledAmount; i++) {
counter += strings[i].mSize;
}
return counter;
}
double digitPercentage() {
int digitsAmount{};
for (int i = 0; i < filledAmount; i++) {
for (int j = 0; j < strings[i].mSize; j++) {
if (isdigit(strings[i].data[j])) {
digitsAmount++;
}
}
}
double digitPercent = (digitsAmount / (double)charAmount()) * 100;
return digitPercent;
}
int filledAmount{};
int strAmount{};
Text* strings = nullptr;
};
void render_text(myString& obj) {
for (int k = 0; k < obj.filledAmount; k++) {
for (int i = 0; i < obj.strings[k].mSize; i++)
cout << obj.strings[k].data[i];
cout << endl;
}
cout << endl;
}
int main() {
myString a(6);
a.addString((char*)"zxc 1v1 forever shadow fiend");
a.addString((char*)"This is a string");
a.addString((char*)"12345");
a.addString((char*)"Hello");
a.addString((char*)"A1oha Dance");
render_text(a);
a.delString(1);
render_text(a);
int maxInd = a.maxString();
cout << "Max string :\n";
for (int i = 0; i < a.strings[maxInd].mSize; i++) {
cout << a.strings[maxInd].data[i];
}
cout << "\n\n";
return 0;
}

I get Abort(core dumped) error when I try and compile the code

I have four parts to this code. One of them is a DVD class and the others are HarryPotterDVD.h, HarryPotterDVD.cpp and HarryPotterDVDDriver.cpp. When I compile the code, it compiles without giving me any errors whatsoever, but when I try to run the compiled executable, I get an Abort(core dumped) error. I think it is because of the way I used the inherited functions. Could you guys please help me figure out how to solve the problem.
DVD.cpp
#include "DVD.h"
DVD::DVD() {
id =0;
title = new char[1];
title[0] = '\0';
director = new char[1];
director[0] = '\0';
}
DVD::DVD(unsigned int i, const char* t, const char* dir) {
id = i;
int len;
for(len = 0; t[len] !='\0'; ++len);
title = new char[len+1];
for(int i = 0; i < len+1; i++) {title[i]=t[i];}
int len2;
for(len2=0; dir[len2] !='\0'; ++len2);
director = new char[len2+1];
for(int j = 0; j<len2+1; j++) {director[j] = dir[j];}
}
DVD::DVD(const DVD &d): id(d.id) {
int len;
for(len=0; d.title[len] !='\0'; ++len);
title = new char[len+1];
for(int j = 0; j < len+1; j++) {
title[j] = d.title[j];
}
int len2;
for(len2=0; d.director[len2] != '\0'; ++len2);
director = new char[len2+1];
for(int j = 0; j<len2 +1; j++) {
director[j] = d.director[j];
}
}
DVD::~DVD() {
if (title) {
delete [] title;
}
if (director) {
delete [] director;
}
}
int DVD::getID() {
return id;
}
char* DVD::getTitle() {
return title;
}
char* DVD::getDirector() {
return director;
}
void DVD::display() {
cout << '[' << id << '.' << ' ' << title << '/' << director << ']' << endl;
}
void DVD::setID(unsigned int i) {
id = i;
}
void DVD::setTitle(const char* t) {
delete [] title;
int len;
for(len = 0; t[len] !='\0'; ++len);
title = new char[len+1];
for(int i = 0; i < len+1; i++) {title[i]=t[i];}
}
void DVD::setDirector(const char* dir) {
delete [] director;
int len2;
for(len2=0; dir[len2] !='\0'; ++len2);
director = new char[len2+1];
for(int j = 0; j<len2+1; j++) {director[j] = dir[j];}
}
DVD& DVD::operator= (const DVD& arg) {
id = arg.id;
int len;
for(len = 0; arg.title[len] !='\0'; ++len);
title = new char[len+1];
for(int i = 0; i < len+1; i++) {title[i]=arg.title[i];}
int len2;
for(len2=0; arg.director[len2] !='\0'; ++len2);
director = new char[len2+1];
for(int j = 0; j<len2+1; j++) {director[j] = arg.director[j];}
return *this;
}
HarryPotterDVD.h
#ifndef _HarryPotterDVD_
#define _HarryPotterDVD_
#include<iostream>
#include "DVD.h"
using namespace std;
class HarryPotterDVD : public DVD {
int episode;
char * antagonist;
public:
HarryPotterDVD(unsigned int i, char* t, char* dir, int n, char* ant);
HarryPotterDVD();
HarryPotterDVD(HarryPotterDVD& d);
~HarryPotterDVD();
int getEpisode();
char* getAntagonist();
void display();
void setEpisode(unsigned int e);
void setAntagonist(const char* c);
HarryPotterDVD& operator= (HarryPotterDVD& arg);
};
#endif
HarryPotterDVD.cpp
#include "HarryPotterDVD.h"
#include<iostream>
using namespace std;
HarryPotterDVD::HarryPotterDVD(unsigned int i, char* t, char* dir, int n, char* ant): DVD( i , t , dir) {
episode = n;
int len;
for(len = 0; ant[len] !='\0'; ++len);
antagonist = new char[len+1];
for(int j = 0; j < len+1; j++) {antagonist[j]=ant[j];}
}
HarryPotterDVD::HarryPotterDVD(HarryPotterDVD &d) {
DVD::setID(d.DVD::getID());
DVD::setTitle(d.DVD::getTitle());
DVD::setDirector(d.DVD::getDirector());
episode = d.episode;
int len;
for(len = 0; d.antagonist[len] != '\0'; len++);
antagonist = new char[len + 1];
for(int i = 0; i < len; i++){
antagonist[i] = d.antagonist[i];
}
antagonist[len+1] = '\0';
}
HarryPotterDVD::HarryPotterDVD() {
episode = -1;
char* tmp = "";
antagonist = tmp;
}
HarryPotterDVD::~HarryPotterDVD(){
delete [] antagonist;
}
int HarryPotterDVD::getEpisode(){
return episode;
}
char * HarryPotterDVD::getAntagonist(){
return antagonist;
}
void HarryPotterDVD::display(){
cout << "[" << DVD::getID() << ". HP" << episode;
cout << ":" << DVD::getTitle() << "/" << DVD::getDirector();
cout << "/" << antagonist << "]" << endl;
}
void HarryPotterDVD::setEpisode(unsigned int e){
episode = e;
}
void HarryPotterDVD::setAntagonist(const char * c){
delete [] antagonist;
int len;
for(len = 0; c[len] != '\0'; len++);
antagonist = new char[len + 1];
for(int i = 0; i < len; i++){
antagonist[i] = c[i];
}
antagonist[len+1] = '\0';
}
HarryPotterDVD& HarryPotterDVD::operator= (HarryPotterDVD &d){
delete [] antagonist;
episode = d.episode;
int len3;
for(len3 = 0; d.antagonist[len3] != '\0'; len3++);
antagonist = new char[len3 + 1];
for(int i = 0; i < len3; i++){
antagonist[i] = d.antagonist[i];
}
antagonist[len3+1] = '\0';
DVD::operator=(d);
/*
setID(d.getID());
int len;
for(len = 0; d.getTitle()[len] != '\0'; len++);
char * tit = new char[len+1];
for(int i = 0; i < len; i++){
tit[i] = d.getTitle()[i];
}
tit[len] = '\0';
setTitle(tit);
int len2;
for(len2 = 0; d.getDirector()[len2] != '\0'; len2++);
char* dire = new char[len2+1];
for(int i = 0; i < len2; i++){
dire[i] = d.getDirector()[i];
}
dire[len2] = '\0';
setDirector(dire);
*/
return* this;
}
HarryPotterDVDDriver.cpp
#include<iostream>
using namespace std;
#include"DVD.h"
#include"HarryPotterDVD.h"
int main() {
HarryPotterDVD h1;
HarryPotterDVD h2(1, "Chamber of Secrets", "Chris Columbus", 2, "Tom Riddle");
HarryPotterDVD h3(h2);
h1 = h3;
cout << h2.getEpisode() << endl;
cout << h2.getAntagonist() << endl;
h3.display();
h1.setEpisode(5);
h1.setAntagonist("Prabesh");
h1.display();
}
In the default constructor of HarryPotterDVD, you are assigning a random pointer to member variable antagonist which is not created with new[]
HarryPotterDVD::HarryPotterDVD() {
episode = -1;
char* tmp = "";
antagonist = tmp;
}
In the operator=()function, when the statement h1=h3; is being executed, you are deleting the antagonist using delete[] which is causing the segmentation fault.
delete is null-safe. So, in your default constructors, you can just make the pointers to nullptr and delete of them during assigning won't cause any errors. If you change this way, your issue should go away.
HarryPotterDVD::HarryPotterDVD() {
episode = -1;
antagonist = nullptr;
}

Exception Error while char input from file in 2D Pointers and Regrowing

I am trying to input names from a file to a double pointer. Since, the file structure is as such that i don't know how many names will I encounter. I am regrowing my pointer both 2D and 1D at run time. But the problem is that since i am using fin.eof() in my while loop. When all the names have been entered, the loop doesn't detect the end of file and adds another array to the 2D pointer and since it hasn't any memory allocated yet. And then it tries to add '\0' to unallocated memory and then it throws an exception error.
#include <iostream>
#include <fstream>
using namespace std;
void OneDRegrow(char * & ptr, int & size)
{
char * temp = new char[size];
for (int i = 0; i < size; i++)
{
temp[i] = ptr[i];
}
if(!ptr)
delete[] ptr;
ptr = temp;
size++;
}
void TwoDRegrow(char ** & ptr, int & size)
{
char ** temp = new char*[size + 1];
for (int i = 0; i < size; i++)
{
temp[i] = ptr[i];
}
delete[] ptr;
ptr = temp;
temp = nullptr;
size++;
}
bool Read(ifstream & fin, char ** & ptr, int & rows)
{
if (!fin.is_open())
return false;
rows = 0;
int cols = 0;
char ch = '\0';
while (!fin.eof()) {
TwoDRegrow(ptr, rows);
cols = 0;
fin >> ch;
while (ch != ';') {
OneDRegrow(ptr[rows-1], cols);
ptr[rows - 1][cols-1] = ch;
fin >> ch;
}
ptr[rows - 1][cols] = '\0';
}
}
void Print2D(char ** ptr, int size)
{
for (int i = 0; i < size; i++)
{
cout << ptr[i] << endl;
}
}
int main()
{
int size;
char ** ptr = NULL;
ifstream fin("input.txt", ios::in);
Read(fin, ptr, size);
Print2D(ptr, size);
system("pause");
return 0;
}
Input from my file is as follows:
Roger;
James;
Mathew;
William;
Samantha;
Do it the right way
while (fin >> ch) {
TwoDRegrow(ptr, rows);
cols = 0;
while (ch != ';') {
...
Never (almost) use eof as the condition in a while loop, for exactly the reasons you have found.

Trouble filling a c++ array, only last item at every index

Firstly, this is for a class so there are limitations on what we can and can't do, plus I am extremely new to c++ and programming in general, so that is why the code is probably a little crap.
I am at my wits end trying to understand why when I display the item_list using the first set of cout lines within the first for loop, it displays each individual item as it should be (its a list of skyrim ingredients and their effects).
However, when the second for loop executes, the item_list is filled with nothing but the last item that should have been inserted (wisp wrappings and their effects).
Even just pointing me in the right direction would be GREATLY appreciated :)
cheers
int client::fill_list(int size_in, int h1size, int h2size)
{
char temp[ASIZE] = {'\0'};
int j = 0;
ifstream ifile;
ifile.open("test.txt");
if(ifile.is_open())
{
for(int i = 0; i < size_in; ++i)
{
if(ifile.good())
{
j = 0;
do
{
temp[j] = char(ifile.get());
++j;
}while(ifile.peek() != '*');
temp[j] = char(ifile.get());
copy(client_item.name, temp, j);
}
if(ifile.good())
{
j = 0;
do
{
temp[j] = char(ifile.get());
++j;
}while(ifile.peek() != '*');
temp[j] = char(ifile.get());
copy(client_item.effect1, temp, j);
}
if(ifile.good())
{
j = 0;
do
{
temp[j] = char(ifile.get());
++j;
}while(ifile.peek() != '*');
temp[j] = char(ifile.get());
copy(client_item.effect2, temp, j);
}
if(ifile.good())
{
j = 0;
do
{
temp[j] = char(ifile.get());
++j;
}while(ifile.peek() != '*');
temp[j] = char(ifile.get());
copy(client_item.effect3, temp, j);
}
if(ifile.good())
{
j = 0;
do
{
temp[j] = char(ifile.get());
++j;
}while(ifile.peek() != '*');
temp[j] = char(ifile.get());
copy(client_item.effect4, temp, j);
}
reference.into_list(i,client_item);
cout << reference.item_list[i].name;
cout << reference.item_list[i].effect1;
cout << reference.item_list[i].effect2;
cout << reference.item_list[i].effect3;
cout << reference.item_list[i].effect4;
getchar();
}
}
for(int k = 0; k < SIZE; ++k)
{
cout << reference.item_list[k].name;
cout << reference.item_list[k].effect1;
cout << reference.item_list[k].effect2;
cout << reference.item_list[k].effect3;
cout << reference.item_list[k].effect4;
}
getchar();
return 0;
}
...
int table::into_list(int index, item&item_in)
{
if(index < SIZE)
{
item_list[index] = item_in;
return 0;
}
else
return 1;
}
...
Header for the table class
#include "hash.h"
class table
{
public:
table()
{
item_list = new item [SIZE];
}
~table();
int fill(item*);
int insert(item&, nHash&);
int insert(item&, eHash&, int);
int retrieve(char*,item*,int);
int remove(int,item&);
int remove(int);
int check_hash(int,int,int);
int keygen(char*, int);
int from_list(int, item&);
int into_list(int, item&);
//private:
item * item_list;
nHash name_table;
eHash ef1_table;
eHash ef2_table;
eHash ef3_table;
eHash ef4_table;
};
....
Beginning of main
#include "client.h"
int main()
{
client program;
program.fill_list(SIZE,HNSIZE,HESIZE);
for(int i = 0; i < SIZE; ++i)
{
cout << program.reference.item_list[i].name;
cout << program.reference.item_list[i].effect1 << endl;
cout << program.reference.item_list[i].effect2 << endl;
cout << program.reference.item_list[i].effect3 << endl;
cout << program.reference.item_list[i].effect4 << endl;
}
....
item header
#include <iostream>
#include <fstream>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <cmath>
using namespace std;
const int ASIZE = 30;
const int SIZE = 92;
const int HNSIZE = 41;
const int HESIZE = 17;
struct item
{
item();
~item();
char * name;
char * effect1;
char * effect2;
char * effect3;
char * effect4;
int count;
//int keygen(int,int);
/*int name_key;
int ef1_key;
int ef2_key;
int ef3_key;
int ef4_key;*/
};
It's possible that part of the problem is how you make copies of client_item here:
reference.into_list(i,client_item);
This just assigns client_item to item_list like so:
item_list[index] = item_in;
...but since item is defined like this:
struct item
{
item();
~item();
char * name;
char * effect1;
...
...all of the items in item_list will have pointers (like name, etc.) that point to the same memory as the memory in client_item.
For example, after each assignment, the pointers item_list[index].name and item_in.name will have the same value. (You can check that by printing both pointers, if you're curious.) Since they both point to the same memory, if you change what's stored at that memory, both objects will appear to change at the same time.
That means that subsequent changes to client_item -- like copying a new string into one of the places that it points -- will affect all of the saved items as well.