In these cycles
char ***full_info = new char**[person_num]; for (int i = 0; i < person_num; i++){ full_info[i] = new char *[5]; for (int j = 0; j < 5; j++){ full_info[i][j] = new char[10]; } }
You dynamically allocated arrays at three levels:
char ***full_info = new char**[person_num]; full_info[i] = new char *[5]; full_info[i][j] = new char[10];
Therefore, on each of these levels you need to free the allocated memory.
Then you have a suggestion in the program.
full_info[0][0] = "Sidorow"; full_info[0][1] = "Ivan"; full_info[0][2] = "24"; full_info[0][3] = "1987"; full_info[0][4] = "Filatova 20";
String literals have a static memory duration. That is, they are distributed by the compiler at the stage of compilation in a static memory area ..
So in the above cycles, you have allocated memory.
full_info[i][j] = new char[10];
This means that the full_info[i][j] pointers point to the first bytes of the selected character arrays char[10] . However, you then rewrite the values of these pointers with the addresses of string literals like, for example, full_info[0][0] = "Sidorow"; , and, thereby, lose addresses of the selected character arrays in the above cycle. As a result, you have a memory leak. You will not be able to correctly free all the allocated memory, because the addresses of the selected character arrays have been lost.
It would be correct to copy string literals into selected arrays, such as
std::strcpy( full_info[0][0], "Sidorow" );
However, you have insufficiently allocated character arrays and, for example, this string literal "Filatova 20" , which has type const char[12] does not fit in an array of type char[10] .
Keep in mind that in these cycles
//скопировать старый массив указателей в новый for (int i = 0; i < person_num - 1; i++){ for (int j = 0; j < num_of_colls; j++){ temp_full_info[i][j] = full_info[i][j]; } temp_full_info[i] = full_info[i]; }
you also copy the pointers themselves instead of copying the contents of character arrays of the "lower" level. As a result, you again have a memory leak.
With regard to the release of memory, the memory allocated in the above cycles, is released in reverse order.
for (int i = 0; i < person_num; i++){ for (int j = 0; j < 5; j++){ delete [] full_info[i][j]; } delete [] full_info[i]; } delete [] full_info;
If you have values of the number of elements of the arrays, respectively, equal to the values of 5 and 10 (or a slightly larger value), are constant, then you could do it easier. for example
char ( *full_info )[5][10] = new char[person_num][5][10];
Then it will be very easy to delete the allocated memory.
delete [] full_info;
Instead of manually allocating and freeing memory, you could use the standard std::vector and std::string classes.
For example,
std::vector<std::vector<std::string>> full_info( person_num, std::vector<std::string>( 5 ) );
vector<vector<string>>, notchar***. - VladD