ОК, так что вы хотите использовать строки char *, предположительно, чтобы справиться с ними на будущее.Это замечательно.Но сначала вам понадобится ускоренный курс в заповеди управления c-string ...
Вы должны соединиться каждые new
с delete
Ваша цель - попытаться минимизировать использование памяти, верно?Ну, каждый раз, когда вы создаете строку с new
, но затем не удаляете ее, вы теряете эту память.Это плохая практика в целом, но и определенная потеря памяти.В вашем случае вы выделяете new []
для создания массива, а вызовы new []
должны быть сопряжены с delete []
.Итак, в вашей функции PrimeFactor:
strcpy( new_p, p_str );// copy the global string to new place
strcat( new_p, tmpstr );// append new integer value
// delete original contents of p_str
delete [] p_str;
p_str = new_p ; // let glocal string be renewed with appending new result
Вам также понадобится delete []
в самом конце вашей программы, чтобы очистить память p_str перед ее выходом.
Ты всегда будешь освобождать место для нулевого терминатора
Когда компьютер читает к-струну, он не знает заранее, как долго это будет продолжаться.Если у вас есть символ [100], инициализированный содержимым «Привет», как компьютер, как известно, останавливается после «i», а не «H» или символа 5 после «i»?C-строки недопустимы, если они не заканчиваются нулевым терминатором, записанным как '\ 0'.Нуль-терминатор указывает компьютеру: «Хорошо, мы закончили».Строка окончена.Это довольно изящно, но могут возникнуть проблемы, потому что нулевой терминатор занимает место в массиве символов.Для сохранения «Привет» требуется char [3];
- char[0]
- это «H», char[1]
- это «i», а char[2]
- «\ 0».Таким образом, ваш новый код выделения строк должен выглядеть следующим образом:
char * tmpstr = new char[ countSize(i) + 1 ] ;// allocate according to size of integer (not waste memory)
...
char * new_p = new char [ size + countSize(i) + 1 ];
Обратите внимание на + 1
s.Это необходимо для того, чтобы в ваших строках оставалось место для нулевого терминатора.
Вы должны использовать функции, безопасные для строк
sprintf
, strcpy
и strcat
(и другие) устарели в пользу новых функций sprintf_s
, strcpy_s
и strcat_s
._S означает «безопасный».Эти функции принимают дополнительный параметр для размера изменяемой строки и гарантируют, что ограничение размера не нарушено.Все функции строкового модификатора гарантируют, что вышеупомянутый нулевой терминатор прикреплен, но в вашем коде вы не дали им достаточно места для этого.Таким образом, функции, не являющиеся безопасными для строк, записывали один символ, вставляя вашу объявленную память в неизвестную память - плохо - очень плохо.Строково-безопасные версии этих функций вместо этого могли бы привести к сбою вашей программы с ошибкой, предупреждающей вас о том, что что-то не так и нужно исправить.Строковая безопасная реализация ваших функций будет выглядеть так:
int tmpstrSize = countSize( i ); // calculate tmpstrSize once
char * tmpstr = new char[ tmpstrSize + 1 ] ;// allocate according to size of integer (not waste memory)
sprintf_s( tmpstr, tmpstrSize + 1, "%d ", i); // NOTE : if not have the blank after %d -> no space
...
int new_pSize = size + tmpstrSize; // calculate new_pSize once
char * new_p = new char [ new_pSize + 1 ];
strcpy_s( new_p, new_pSize, p_str );// copy the global string to new place
strcat_s( new_p, new_pSize, tmpstr );// append new integer value
Теперь вы в порядке и в безопасности, и если что-то пойдет не так, вы будете знать .
Вы должны написать код C ++ на языке C ++
По правде говоря, программа, которую вы написали выше, на самом деле не C ++, а C. Конечно, она будет нормально работать всреда C ++, но метод полностью основан на C.Программы на C ++ используют std::string
s для строк и std::vector
s для списков целых чисел.Так что, эй, я понимаю, что вы хотите изучить материал низкого уровня для этого испытания, я сам там был.Но как только вы знаете, как это сделать, функциональность C ++, которая делает практически все, что я описал выше, неуместной для обработки строк, становится находкой , и вы никогда не захотите возвращаться назад.
В качестве небольшого примечания, я рекомендую проверить Сито Эратосфена для проверки простого числа.Это хорошее упражнение для реализации, и оно даст вашему коду огромный прирост производительности.