Ошибка отладки утверждения даже при использовании delete []

0

Я новичок в программировании и недавно написал этот код

#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, но я удаляю ее из функции?

  • 0
    Какую ошибку вы видите?
  • 0
    Я не уверен, что это должно делать: arr[remove[i]]=1 , но это приведет к неопределенному поведению.
Показать ещё 1 комментарий
Теги:
visual-studio-debugging

3 ответа

5

Возвращаемое значение 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[] работает правильно. Кроме того, большинство, если не все упомянутые проблемы исчезли. Работа с заданиями, отсутствие утечек памяти и т.д.

1
    source="Hello how are you";
    remove="Hi Its me";

Это не верно. Правильный путь:

    strcpy( source, "Hello how are you" );
    strcpy( remove, "Hi Its me" );

Вы не можете "удалить" постоянную строку. Вы можете удалить массив/память, выделенную "новым".

  • 0
    В случае простого типа, такого как «char», нет разницы с delete без []. Скобки необходимы, если элементы массива являются объектами и требуют явного вызова его деструктора.
  • 1
    @ i486-- char* chars = new char[100]; delete chars; является неопределенным поведением. На практике это может сработать или может случиться так, что освобождается только один байт из 100-байтового распределения (в зависимости от того, как работает реализация). Но правило таково: если вы используете new[] , убедитесь, что вы также используете delete[] .
Показать ещё 4 комментария
-1

источник передается по значению. Вызов источника delete [] не будет влиять на источник в основной функции.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню