Mat 257 Ответов: 4

C++ удаление мусорной памяти, сбой кода


всем привет. у меня еще один беспорядок.
я уверен, что это зависит от неправильного удаления мусора momory.
после вызова функции "Presentazione", когда компилятор достигает отмеченной строки, он терпит крах.
это наверняка пробем памяти.

<pre>
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <ctime>
using namespace std;

string* mostraCarta1()
{ string* Carta1 = new string[7];
  Carta1[0]=" _____ ";
  Carta1[1]="|A    |";
  Carta1[2]="|  ^  |";
  Carta1[3]="| / \\ |";
  Carta1[4]="| \\ / |";
  Carta1[5]="|  V  |";
  Carta1[6]="|____V|";

	return Carta1;
//delete[] Carta1;	
}

string* mostraCarta2()
{	string* Carta2 = new string[7];
	Carta2[0]=" _____ "; 
	Carta2[1]="|A    |"; 
	Carta2[2]="|  ^  |"; 
	Carta2[3]="| /.\\ |";
	Carta2[4]="|(_._)|";
	Carta2[5]="|  |  |";
	Carta2[6]="|____V|";
	
	return Carta2;
//delete[] Carta2;	
}

string* mostraCarta3()
{	string* Carta3 = new string[7];
	Carta3[0]=" _____ "; 
	Carta3[1]="|A    |"; 
	Carta3[2]="|  ^  |"; 
	Carta3[3]="| ( ) |";
	Carta3[4]="|(_'_)|";
	Carta3[5]="|  |  |";
	Carta3[6]="|____V|";

	return Carta3;
//delete[] Carta3;	
}

string* mostraCarta4()
{	string* Carta4 = new string[7];
	Carta4[0]=" _____ "; 
	Carta4[1]="|A    |"; 
	Carta4[2]="| _ _ |"; 
	Carta4[3]="|( v )|";
	Carta4[4]="| \\ / |";
	Carta4[5]="|  V  |";
	Carta4[6]="|____V|";
	
	return Carta4;
//delete[] Carta4;
}

void Presentazione()
{   string Visualizza[7][5];
	string *Valori;
	Valori=mostraCarta1();
		for (int j = 0; j <7; j++)
		   {Visualizza[j][1]=*(Valori+j);
		   }	
	Valori=mostraCarta2();
		for (int j = 0; j <7; j++)
		   {Visualizza[j][2]=*(Valori+j);
		   }
	Valori=mostraCarta3();
		for (int j = 0; j <7; j++)
		   {Visualizza[j][3]=*(Valori+j);
		   }
	Valori=mostraCarta4();
		for (int j = 0; j <7; j++)
		   {Visualizza[j][4]=*(Valori+j);
		   }
	Valori=mostraCarta2();
		for (int j = 0; j <7; j++)
		   {Visualizza[j][5]=*(Valori+j);
		   }	

for (int j = 0; j <7; j++)
{cout<<Visualizza[j][1]<<endl;
 }
system("pause");
system("CLS");
for (int j = 0; j <7; j++)
{cout<<Visualizza[j][1]<<Visualizza[j][2]<<endl;
 }
system("pause");
system("CLS");
for (int j = 0; j <7; j++)
{cout<<Visualizza[j][1]<<Visualizza[j][2]<<Visualizza[j][3]<<endl;
 }
system("pause");
system("CLS");
//------------------------------CRASH!!!!!!!!!!!!!!!!!!!!
for (int j = 0; j <7; j++)
{cout<<Visualizza[j][1]<<Visualizza[j][2]<<Visualizza[j][3]<<Visualizza[j][4]<<endl;
}
system("pause");
system("CLS");
}


int main()
{Presentazione();

system("pause");
exit(0);
return 0;
}


Что я уже пробовал:

for (int j = 0; j <7; j++)
{cout<<Visualizza[j][1]<<endl;
delete Visualizza[j][1];// tried this in all four subsequent for int loop.  
}

4 Ответов

Рейтинг:
31

Stefan_Lang

1. Вы можете удалять только объекты, созданные в куче. Visualizza это массив, объявленный в стеке, поэтому вы не можете удалить его. Попытка сделать это всегда приведет к краху.

2. Вы выделили массивы строк в своих функциях mostraCarta*(), и вы храните их в переменной Valori Это память, которая должна быть освобождена снова, но вместо этого вы перезаписываете эти указатели и создаете утечки памяти.

3. Чтобы правильно освободить массив, хранящийся в Valori, вы должны использовать оператор удаления массива:

delete [] Valori;
Скобки важны, потому что в противном случае компилятор не знает, указывает ли указатель на один объект или на целый массив элементов.

4. Ваши циклы не использовать правильные значения индекса для массива Visualizza Но Фил . о уже указал на эту проблему в решении 1.

5. вместо простых массивов следует использовать std::vector. Этот класс будет заботиться о памяти, так что вам не нужно будет вручную ее перестраивать. это также избавило бы от необходимости в переменной Valori и циклах копирования. :
std::vector<std::string> mostraCarta3()
{	std::vector<std::string> Carta3(7); // vector with 7 elements
	Carta3[0]=" _____ "; 
	Carta3[1]="|A    |"; 
	Carta3[2]="|  ^  |"; 
	Carta3[3]="| ( ) |";
	Carta3[4]="|(_'_)|";
	Carta3[5]="|  |  |";
	Carta3[6]="|____V|";

	return Carta3;
}
...
void Presentazione()
{   std::vector<std::string> Visualizza[5];
    ...
    Visualizza[2]=mostraCarta3();
    // no need for loop; no need for variable Valori; no need to release memory!
    ...
}


Рейтинг:
27

phil.o

string Visualizza[7][5];

То Visualizza переменная определяется как двумерный массив с 7 элементами в первом измерении и 5 элементами во втором.
Это означает, что первое измерение индексируется от 0 до 6, а второе измерение индексируется от От 0 до 4.

В своем коде вы, похоже, используете индексацию на основе 1 для второго измерения. Попробуйте вычесть 1 из всех методов доступа к индексам второго измерения:
Valori = mostraCarta1();
for (int j = 0; j < 7; j++)
{
   Visualizza[j][0] = *(Valori+j);
}	
Valori = mostraCarta2();
for (int j = 0; j < 7; j++)
{
   Visualizza[j][1] = *(Valori+j);
}
Valori = mostraCarta3();
for (int j = 0; j < 7; j++)
{
   Visualizza[j][2] = *(Valori+j);
}
Valori = mostraCarta4();
for (int j = 0; j < 7; j++)
{
   Visualizza[j][3] = *(Valori+j);
}
Valori = mostraCarta2();
for (int j = 0; j < 7; j++)
{
   Visualizza[j][4] = *(Valori+j);
}	
// Likewise for the rest of your code

Остается проблема, что новый строковый массив создается всякий раз, когда вы вызываете один из методов создания карт. Возможно, вам следует начать с хранения их в массиве; это позволит вызывать эти методы только один раз.
string** mostraCartas = new string*[4];
mostraCartas[0] = mostraCarta1();
mostraCartas[1] = mostraCarta2();
mostraCartas[2] = mostraCarta3();
mostraCartas[3] = mostraCarta4();


Рейтинг:
2

CPallini

Обратите внимание на ваш Carta объекты-это константы. Вам не нужно динамически выделять память, ни явно, ни неявно. Например:

#include <iostream>
#include <array>
using namespace std;




int main()
{
  using namespace std::literals::string_literals;
  const array < const array < const string, 7 >, 1> carta =
  {// here the array, for illustrative purpose, has just one item, fill it with all the required ones
    {
      " _____ "s,
      "|A    |"s,
      "|  ^  |"s,
      "| / \\ |"s,
      "| \\ / |"s,
      "|  V  |"s,
      "|____V|"s
    }
  };


  for ( const auto & c : carta )
    for ( const auto s : c )
      cout << s << "\n";

}


Рейтинг:
0

Mat 257

hi everyone;
your suggestions solved my mess up.
now i have another question, but is bit broad:
suppose i want to set a strings array as a result of different row vector toghether;
let s assume i want to gourp 3 strings vectors, 1) with 5 characters, 2) 8 characters 3) 2 characters.
the result would be and "assimetric " array. in maths this is overcome by changing the missings values of smaller vector respect the greater, with 0
example
V1 [5]= {a,a,a,a,a}
V2 [8]={a,a,a,a,a,a,a,a}
V3 [2]={a,a}
in maths i would have
Array[8][1]={a,a,a,a,a,0,0,0}
Array[8][2]={a,a,a,a,a,a,a,a,}
Array[8][3]={a,a,0,0,0,0,0,0}
will the compiler act in the same way?? thanks