Я новичок в программировании и недавно написал этот код
#include<iostream>
using namespace std;
void removeAllCharacters(char * , char * );
void printArray(char*);
void deleteArrays(char*,char*);
int main()
{
char * source,*remove;
source=new char[18];
remove=new char[10];
source="Hello how are you";
remove="Hi Its me";
removeAllCharacters(source,remove);
printArray(source);
deleteArrays(source,remove);
system("pause");
return 0;
}
void removeAllCharacters(char * source, char * remove)
{
int N1=strlen(source)+1;
int N2=strlen(remove)+1;
bool arr[128] = {false};
for(int i=0;i<N2-1;i++)
{
arr[remove[i]]=1;
}
char *newSource=new char[N1];
for(int i=0,j=0;i<N1-1;i++)
{
if(arr[source[i]]==0)
{
newSource[j++]=source[i];
}
}
delete [] source;
source=newSource;
newSource=0;
}
void printArray(char* arr)
{
int N=strlen(arr)+1;
for(int i=0;i<N;i++)
{
cout << arr[i];
}
cout << endl << endl;
}
void deleteArrays(char* arr1,char*arr2)
{
delete [] arr1;
arr1=0;
delete[]arr2;
arr2=0;
}
Я попробовал отладку и обнаружил, что ошибка возникает при удалении [] source; в функции removeCharacters. Я попытался найти решение в Интернете, но я не смог его найти. Почему эта ошибка возникает? Является ли ошибка, потому что я выделил динамическую память из main, но я удаляю ее из функции?
Возвращаемое значение new[]
является значением указателя. Независимо от того, что происходит, когда вы вызываете вызов для delete[]
, необходимо использовать то же точное значение указателя.
Очевидно, это нарушит вышеприведенное правило:
source=new char[18];
remove=new char[10];
source="Hello how are you";
remove="Hi Its me";
Вы назначаете new[]
, но заменяете возвращаемое значение значением строкового литерала. Другими словами, значение указателя, требуемое для вызова delete[]
теперь исчезло.
Вот пример того, что вы должны были сделать:
char str1[] = "Hello how are you";
char str2[] = "Hi Its me";
source=new char[sizeof(str1)];
remove=new char[sizeof(str2)];
strcpy(source, str1);
strcpy(remove, str2);
Обратите внимание, что мы создали два буфера, инициализированных данными. Затем мы аккуратно выделяем достаточно памяти для символов (плюс завершающий нуль) вместо того, чтобы считать символы и, возможно, получить что-то неправильно.
Затем функция strcpy
копирует символы в другой буфер.
У вас также есть другая ошибка:
source=newSource
Вы сразу увидите, что у source
возврата нет указателя, который вы только что назначили. Причина в том, что source
- это параметр значения, поэтому локальный для функции - присвоение ему ничего не делает с фактическим значением, переданным функции, так как любое присваивание просто возвращается в дымку при возврате функции.
Кроме того, это вы новичок в программировании C++, вы могли бы начать использовать std::string
а не char * для строковых данных. Создание строк с использованием new[]
- это подход динозавра в C++. Вместо этого используйте std::string
. Вы действительно должны стремиться не заниматься бизнесом создания таких строк:
char *newSource=new char[N1];
Это приводит к утечке памяти, а иногда и к спагетти-подобной логике в отслеживании выделенной памяти, так что функция delete[]
работает правильно. Кроме того, большинство, если не все упомянутые проблемы исчезли. Работа с заданиями, отсутствие утечек памяти и т.д.
source="Hello how are you";
remove="Hi Its me";
Это не верно. Правильный путь:
strcpy( source, "Hello how are you" );
strcpy( remove, "Hi Its me" );
Вы не можете "удалить" постоянную строку. Вы можете удалить массив/память, выделенную "новым".
char* chars = new char[100]; delete chars;
является неопределенным поведением. На практике это может сработать или может случиться так, что освобождается только один байт из 100-байтового распределения (в зависимости от того, как работает реализация). Но правило таково: если вы используете new[]
, убедитесь, что вы также используете delete[]
.
источник передается по значению. Вызов источника delete [] не будет влиять на источник в основной функции.
arr[remove[i]]=1
, но это приведет к неопределенному поведению.