forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   C++ (http://forum.boolean.name/forumdisplay.php?f=22)
-   -   delete [] const char (http://forum.boolean.name/showthread.php?t=19172)

impersonalis 15.05.2014 13:49

delete [] const char
 
Меня всё устраивает, я ко всему привык, я это знаю. НО. Не кажется ли вам это слегка нелогичным?
Ну почему, почему одновременно:
1) нельзя менять данные, адресуемые указателем const char *
2) можно высвободить память, адресуемую указателем const char *
Код:

    const char *n=new char[10];
    n[0]=0; // НЕЛЬЗЯ
    delete[]n;//МОЖНО

Типа снёс к чертям кусок памяти - это ничего страшного, это же не изменение данных. Можно возразить, что оператор delete формально применяется не к данным, а к самому указателю на них. Но ведь
Код:

const char * const n=new char[10];
тоже можно удалить.
Выходит бажного деструктор пофиксит действует ещё одно правило: разрешается высвободить память с любым спецификаторм доступа.
Отличный способ выстрелить себе в ногу, попробовав удалить константную строку.
Код:

    const char * const n="222";
    cout<<n<<endl;
    delete[]n;

И хоть приведённая конструкция на GCC не взывала сбоя, в 5.2.2. ("Язык программирования C++" Страуструпа) конструкции типа
Код:

    char *n="111";
    n[2]=0;

сопровождаются отметкой о неопределённости результата.

Кстати, пользуясь случаем, хочу провести мини-тест используемых компиляторов. Сообщите результат выполнения кода
Код:

const char *p="111";
    const char *q="111";
    if(p==q){
        cout<<"eq"<<endl;
    }
    else{
        cout<<"!eq"<<endl;
    }

и используемый компилятор (на всякий случай и IDE; опционально - флаги компиляции, режим сборки).

SBJoker 15.05.2014 14:56

Ответ: delete [] const char
 
Xcode 5.1.1, Apple LLVM 5.1, opt. flags: -O0
result: eq

HolyDel 15.05.2014 16:03

Ответ: delete [] const char
 
msvs 2012. не компилируется))

после дописания main и прочего выводит eq

Mr_F_ 15.05.2014 16:36

Ответ: delete [] const char
 
msvc 2010: eq

Samodelkin 15.05.2014 20:04

Ответ: delete [] const char
 
Цитата:

Сообщение от impersonalis (Сообщение 280789)
Меня всё устраивает, я ко всему привык, я это знаю. НО. Не кажется ли вам это слегка нелогичным?
Ну почему, почему одновременно:
1) нельзя менять данные, адресуемые указателем const char *
2) можно высвободить память, адресуемую указателем const char *

Потому что память высвобождает система (например вызовом через WinAPI), до вызова ничего противозаконного не происходит, а компилятор не имеет представление что внутри winapi творится, ведь dll линкуется во время запуска приложения.

И кстати delete можно перегрузить так, что он ничего менять/удалять не будет.

Идея ооп также заключается в том что ты сам должен позаботиться чтобы деструктор корректно удалил данные не испортив их.

А также имхо квалификаторы в с++ в целом для программиста - их всегда можно поменять кастами.

pozitiffcat 04.06.2014 14:40

Ответ: delete [] const char
 
Цитата:

Сообщение от impersonalis (Сообщение 280789)
Меня всё устраивает, я ко всему привык, я это знаю. НО. Не кажется ли вам это слегка нелогичным?
Ну почему, почему одновременно:
1) нельзя менять данные, адресуемые указателем const char *
2) можно высвободить память, адресуемую указателем const char *
Код:

    const char *n=new char[10];
    n[0]=0; // НЕЛЬЗЯ
    delete[]n;//МОЖНО

Типа снёс к чертям кусок памяти - это ничего страшного, это же не изменение данных. Можно возразить, что оператор delete формально применяется не к данным, а к самому указателю на них. Но ведь
Код:

const char * const n=new char[10];
тоже можно удалить.
Выходит бажного деструктор пофиксит действует ещё одно правило: разрешается высвободить память с любым спецификаторм доступа.
Отличный способ выстрелить себе в ногу, попробовав удалить константную строку.
Код:

    const char * const n="222";
    cout<<n<<endl;
    delete[]n;

И хоть приведённая конструкция на GCC не взывала сбоя, в 5.2.2. ("Язык программирования C++" Страуструпа) конструкции типа
Код:

    char *n="111";
    n[2]=0;

сопровождаются отметкой о неопределённости результата.

Кстати, пользуясь случаем, хочу провести мини-тест используемых компиляторов. Сообщите результат выполнения кода
Код:

const char *p="111";
    const char *q="111";
    if(p==q){
        cout<<"eq"<<endl;
    }
    else{
        cout<<"!eq"<<endl;
    }

и используемый компилятор (на всякий случай и IDE; опционально - флаги компиляции, режим сборки).


Твоюж мать! У тебя не массив константный, а данные в нем, массив грохнуть можно (указатель точнее), данные менять нет, ВСЕ!
З.Ы. деструкторы могут выполняться для константных объектов

impersonalis 04.06.2014 15:18

Ответ: delete [] const char
 
Во-первых, я попросил бы не касаться моих родственников.
Во-вторых - перестать истерить.
В-третьих - замечание интересное, но в рамках уже сказанного выше - не актуальное.

Я прям так и вижу, как пользователь брызжа слюной набирал этот гневный пост (даже поленился фрагмент цитирования выделить, хотя отвечает лишь на часть поста).

Вот если б вместо эмоций повнимательнее присмотреться к:
Цитата:

Меня всё устраивает, я ко всему привык, я это знаю. НО. Не кажется ли вам это слегка нелогичным?
то можно сделать вывод, что вопрос то стоит несколько в иной плоскости. И именно такие "метафизические" вопросы я частенько и задаю, предварив их соответствующей пометкой. И именно к этому мы и пришли "удаление не есть модификация" (хоть несколько странно с обывательской точки зрения, но объекты как-то надо уничтожать [хотя на практике, компилятор на вряд ли будет очищать память из-под константных строк, т.к. изначально вовлекает их в оптимизации]).
Код:

const char *x;
    const char *y;

    x="123";
    cout<<(void*)x<<endl;
    delete[]x;
    x="234";
    cout<<(void*)x<<endl;

    y=new char[3];
    cout<<(void*)y<<endl;
    delete[]y;
    y=new char[3];
    cout<<(void*)y<<endl;

На самом деле содержимое x ("123") не удалится, память для "234" будет взята новая. При этом y удаляется "по-настоящему": память для второго массива имеет тот же адрес, т.к. она уже доступна для использования.


И ещё:
Цитата:

Сообщение от pozitiffcat (Сообщение 282065)
массив грохнуть можно (указатель точнее), данные менять нет,

смею указать на ошибку: указатель останется "живым". Он, в отличии от адресуемого куска памяти, в приведённых примерах создаётся не в куче (представляет собой т.н. в некоторых книгах "автоматическую" переменную), удалён при вызове delete не будет, и повторно может использоваться для хранения иных адресов. "Грохнута", как Вы выражаетесь, будет память, адресуемая данным указателем. Но впрочем, к чему эти формальности, ведь "в интернете кто-то не прав".


Часовой пояс GMT +4, время: 20:25.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot