Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Архив форумов ЦИТФорума
Море(!) вопросов - Море(!) ответов
 
 FAQFAQ   ПоискПоиск   ПользователиПользователи   ГруппыГруппы   РегистрацияРегистрация 
 ПрофильПрофиль   Войти и проверить личные сообщенияВойти и проверить личные сообщения   ВходВход 
Как правильно задавать вопросы

Можно ли

 
Перейти:  
Этот форум закрыт, вы не можете писать новые сообщения и редактировать старые.   Эта тема закрыта, вы не можете писать ответы и редактировать сообщения.    Список форумов Архив форумов ЦИТФорума -> Программирование
Предыдущая тема :: Следующая тема  
Автор Сообщение
Sasha_builder
Гость





СообщениеДобавлено: Пт Янв 18 2002 21:09    Заголовок сообщения: Можно ли Ответить с цитатой

Привествую всех.

Кто может прояснить, можно ли присваивать значения указателям. Я понимаю, что запретить мне этого никто не может, но меня интересует корректны ли такие действия с точки зрения ОС (ДОС и Виндоуз). Привожу пример программы. Она работает, но я не уверен, можно ли такими приемами пользоваться в более критических (по использованию памяти) программах.

#include
#include

//глобальный указатель
int *PtrGlob;


void ArraySetting(int n)
{
int *ptrLoc;

//запрос памяти, используя локальный указатель
ptrLoc=new int[n];

//присваивание значения локального ук. глобальному
PtrGlob=ptrLoc;

}


void main()
{
int i,n=1000;

//создание массива во внешней функции
ArraySetting(n);

//использование глобального массива
for(i=0;i
Вернуться к началу
zzz



Зарегистрирован: 02.02.2002
Сообщения: 66
Откуда: Rostov-on-Don

СообщениеДобавлено: Сб Янв 19 2002 08:47    Заголовок сообщения: можно, а пример не ботал (-) Ответить с цитатой

-
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Алексанлр
Гость





СообщениеДобавлено: Сб Янв 19 2002 15:52    Заголовок сообщения: Re: Можно ли Ответить с цитатой

Не совсем понятно где пример не работает.

Лично мой совет избегай использования глобальных переменных по возможности.

Что касается примера я лично не увилел, а где же ты уничтожаеш свой массив ?
delete []указатель на массив;
может в этом проблема ?
Вернуться к началу
Александр



Зарегистрирован: 07.10.2003
Сообщения: 276

СообщениеДобавлено: Сб Янв 19 2002 15:57    Заголовок сообщения: Re: Можно ли Ответить с цитатой

Вдогонку , а как ты обращаешся к элементам массива?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Sasha_builder
Гость





СообщениеДобавлено: Сб Янв 19 2002 20:04    Заголовок сообщения: Re: Можно ли Ответить с цитатой

Спасибо, Александр.

Что касается примера, я тоже мало что там увидел, я не знаю, что нужно делать, чтобы не съедался текст, когда постишь примеры. Послал имейл на info@citforum.ru - ни ответа ни привета.

К делу. Пример работает. Ты несомненно прав с глобальными переменными (избегать по возможности), я следую этому правилу. Так вот, уничтожение и есть штука в которой я не уверен (в смысле как на это смотрит ОС). Я прошу памяти во внешней функции для ее локального указателя, присваиваю его значение глобальному (это все можно увидеть в остатках примера), потом использую этот глобальный указатель в функции main() как массив. Вот теперь, могу ли я применить оператор delete к этому глобальному указателю? Вроде я встречал в руководствах, что применение этого оператора к указателю, к которому не применялся new, может приводить к зависанию (по крайней мере для ДОС). У меня как раз такая ситуация: new к локальному указателя, delete к глобальному. Есть идеи? Извини за многословность, но боюсь опять на примере показать не получилось бы.

Александр
Вернуться к началу
Sasha_builder
Гость





СообщениеДобавлено: Сб Янв 19 2002 20:19    Заголовок сообщения: Re: Можно ли Ответить с цитатой

так: PtrGlob[5]=37; a=PtrGlob[5];
Вернуться к началу
zzz



Зарегистрирован: 02.02.2002
Сообщения: 66
Откуда: Rostov-on-Don

СообщениеДобавлено: Сб Янв 19 2002 20:24    Заголовок сообщения: так new и delete должно работать, им пофигу, если пишешь правильно. (-) Ответить с цитатой

-
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Александр



Зарегистрирован: 07.10.2003
Сообщения: 276

СообщениеДобавлено: Вс Янв 20 2002 01:32    Заголовок сообщения: так пример работает ? Ответить с цитатой

Что лично я понял по поводу этих операторов:
1.Присваивать указателю можешь адрес на любой объект но заботиться об уничтожении должен сам.
2.при создании объекта с помощью new указывается тип переменной (класс), это позволяет удалить объект без приведения типов (именно по этой причине более современными считаются функции new и delete в отличии от malloc ), в твоем случае колизия заключается видимо в следующем:
есть глобальный указатель
int *global,
ты создал массив и присвоил адрес первого элемента этому указателю
int *local=new int[10]
global=local,
а теперь представь,
ты удаляешь массив
или delete []local
или delete []global
В первом случае функция delete знает, что
удалить надо именно десять єлементов типа int (компилятор это понимает поскольку имя одно и тоже).А откуда во втором случае можно узнать, что удалить надо именно десять, а не двадцать элементов ??? Видимо необходимо почитать как это делалось для функций malloc и free в случае массива.
3. При объявлении указателя обязательно присваивай ему либо NULL, либо (разные авторы советуют по разному,в этом есть небольшая разница).
тогда
if(global!=NULL) delete global;
при удалении объекта его указатель получает значение NULL
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Sasha_builder
Гость





СообщениеДобавлено: Вс Янв 20 2002 05:02    Заголовок сообщения: Работает, но... Ответить с цитатой

Александр,

компилятор тут не при чем, так как запрос памяти происходит в период исполнения. Должно что-то происходить на уровне ОС, которая эту память выделяет. Вот тут-то мои знания заканчиваются.

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


Спасибо тебе за ответы.

Александр.
Вернуться к началу
Sasha_builder
Гость





СообщениеДобавлено: Вс Янв 20 2002 05:04    Заголовок сообщения: Re: так new и delete должно работать, им пофигу, если пишешь правильно. (-) Ответить с цитатой

zzz,

правильно ли я пишу - это и было то что я не знал...


Спасибо за ответ!

Александр
Вернуться к началу
zzz



Зарегистрирован: 02.02.2002
Сообщения: 66
Откуда: Rostov-on-Don

СообщениеДобавлено: Вс Янв 20 2002 11:43    Заголовок сообщения: не согласен Ответить с цитатой

организует освобождение памяти не компилятор, запоминая, то раз для x выделено 10 байт, то 10 байт и надо прибивать. Это все реализуется самой системой. И компилятор никакие имена, конечно, не запоминает, потому как имен-то и нету. Создай массив из указателей на массив из указателей и так далее, любой вложенности.
И если аккуратно писать, все будет правильно освобождаться.
Многие функции WINAPI (в частности, Net*) получают на вход пустой указатель, сами создают буфер, не возвращая его размер, и этот указатель потом отдается в NetApiBufferFree. Одними глобальными или локальными переменными тут не обойтись.

А почему new и delete более современные? Они только реализацию скрывают, и для более или менее сложных классов требуют подчас ненужной перегрузки, в отличие от malloc.

при удалении объекта его указатель получает значение NULL
а это смотря как удалять, в абсолюте заявление более чем голословное.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Александр



Зарегистрирован: 07.10.2003
Сообщения: 276

СообщениеДобавлено: Вс Янв 20 2002 15:21    Заголовок сообщения: Re: не согласен Ответить с цитатой

Компилятор тут наверное действительно не причем, но откуда программа или ОС знает, что
при применении delete к глобальному указателю что это указатель не на один int, а на массив.
По моему в примере речь шла имеенно об этом.

Не уверен в своей правоте но всетаки выслушал бы еще аргументы.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Александр



Зарегистрирован: 07.10.2003
Сообщения: 276

СообщениеДобавлено: Вс Янв 20 2002 15:37    Заголовок сообщения: Re: не согласен Ответить с цитатой

Кстати а какие системы заботятся об уничтожении данных размещаемых программой в куче ? Я думал это дело самих программ.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
zzz



Зарегистрирован: 02.02.2002
Сообщения: 66
Откуда: Rostov-on-Don

СообщениеДобавлено: Вс Янв 20 2002 16:10    Заголовок сообщения: так вот, Ответить с цитатой

когда дело касается удаления, пишется же не delete, а delete[]. Короче, потому я new и delete и не люблю, что они реализацию скрывают.
А delete применяется для каждого элемента.
Короче, для каждого объекта определяется действие delete. А уж это действие может и другие delete вызывать.

Освобождение ресурсов - это и дело самих программ, и не только. Даже в случае самих программ это дело программиста, как в случае С, или реализована сборка мусора, как в SmallTalk. Например, в NT/2000 можно не закрывать файлы, система их сама закроет, по крайней мере, должна. И для процесса в ядре создаются структуры данных, которые хранят все его открытые хэндлы. При выделении и освобождении памяти не составляет труда определить контекст вызова, и в конце даже в случае смерти программы освободить память и ресурсы. На 9x такие фокусы, насколько я понимаю, не пройдут.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
zzz



Зарегистрирован: 02.02.2002
Сообщения: 66
Откуда: Rostov-on-Don

СообщениеДобавлено: Вс Янв 20 2002 16:15    Заголовок сообщения: при выделении памяти Ответить с цитатой

выделяется системой больше, чем просишь. Прозрачная реализация такого механизма обеспечивается диспетчером памяти на уровне ядра. А все указатели - они только идентифицируют тот объект в ядре, который определяет адрес выделяемого объема памяти, его контекст защиты, его тип доступа и тому подобное. А все вызовы WINAPI транслируются в соответствующие функции ядра, в том числе при выделении и освобождении памяти.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
appower
Гость





СообщениеДобавлено: Ср Янв 23 2002 22:28    Заголовок сообщения: Re: for lamers Ответить с цитатой

В пределах одного процесса, глобальному ука-
зателю можешь присвоить даже указатель на
свои тупые мозги.
Вернуться к началу
Sasha_builder
Гость





СообщениеДобавлено: Чт Янв 24 2002 00:08    Заголовок сообщения: Возможно ты прав, а что-нибудь конструктивнее? Ответить с цитатой

Насчет тупых мозгов - извини.

И все-таки, как поступить?
Вернуться к началу
appower
Гость





СообщениеДобавлено: Пт Янв 25 2002 00:00    Заголовок сообщения: Re: Возможно ты прав, а что-нибудь конструктивнее? Ответить с цитатой

char * global_pointer = 0;
//---------------------------------
struct s
{
char a;
int b;
};
//---------------------------------
void f1(int *val)
{
val = new int[3];
}
//---------------------------------
void f2(char *val)
{
val = new char[3];
}
//---------------------------------
void f3(struct s *val)
{
val = new s[3];
}
//---------------------------------
int main()
{
f1(reinterpret_cast(global_pointer));
delete[]global_pointer;
f2(global_pointer);
delete[]global_pointer;
f3(reinterpret_cast (global_pointer));
delete[]global_pointer;
return 0;
}
//-------------------------------------
создание массива во внешней функции

Внешней чему????????????????????????
Процессу???
Любые указатели корректны, если ты не переда-
ешь их после вызовов CreateProcess(fork,clone
и т.п.) в ф-и дочерних или внешних процессов.
Вернуться к началу
Alexy



Зарегистрирован: 22.10.2003
Сообщения: 48

СообщениеДобавлено: Вс Янв 27 2002 10:15    Заголовок сообщения: Oops Ответить с цитатой

К сожалению этот пример упадёт уже на второй строчке main() - "delete[]global_pointer;" с диагнозом access violation или segmentation fault в UNIX и вот почему:

любая программа имеет 4 сегмента
1. code segment - здесь расположены команды для процессора
2. data segment - здесь расположены глобальные данные процесса/ов (*.exe + dll-и)
3. stack segment - сюда пишут много всего, а среди прочего порядок вызова функций и локальные переменные, в том числе параметры функций
4. heap - здесь размещается динамически выделяемая память (new, malloc)

Глобальные переменные обязательно инициализируются в NULL, чтобы следующий код мог правильно сработать:

SomeSingleton* SomeSingleton::instance =
SomeSingleton::getInstance();
int* SomeSingleton::getInstance()
{
if(!instance)
instance = new SomeSingleton;
return instance;
}
Теперь, что написано в 1 строчки main()
1. положи в stack СОДЕРЖИМОЕ global_poiner,
это NULL. Не адрес global_poiner, а то что
записано по этому адресу
2. всё необходимое для вызова функции
3. call @f1@@int ( Smile )
4. запиши в стек по адресу куда был записан NULL) результат new int[3]
5. очисти stack и сделай return (порядок очистки зависит от calling convention)

В результате у нас есть аллоцированный блок в heap-e, адреса которого мы не знаем и
global_pointer (скажем его адрес будет 2000h)
Так вот, байты 2000h-2003h равны нулю или попросту global_pointer равен нулю

Поэтому 2 строчка будет означать delete NULL;
или delete[] NULL; или free(NULL);
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
appower
Гость





СообщениеДобавлено: Вс Янв 27 2002 16:14    Заголовок сообщения: Re: Oops Ответить с цитатой

Быстро писал. Да ради Бога напиши f1(void **)
или f1(void*&)и присваивай что угодно.Да конечно со стековой переменной слегка лоханулся,но это не принципиально для сути
вопроса,а к мелочам не придирайся, развел демагогию с правилами правописания!
Вернуться к началу
Alexy



Зарегистрирован: 22.10.2003
Сообщения: 48

СообщениеДобавлено: Вс Янв 27 2002 18:41    Заголовок сообщения: Re: Pardon Ответить с цитатой

А аткендава ж я знаю, может ты всерьёз насчёт
f(void*) ???
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
Показать сообщения:   
Этот форум закрыт, вы не можете писать новые сообщения и редактировать старые.   Эта тема закрыта, вы не можете писать ответы и редактировать сообщения.    Список форумов Архив форумов ЦИТФорума -> Программирование Часовой пояс: GMT + 3
Страница 1 из 1

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах


Powered by phpBB © 2001, 2002 phpBB Group
Русская поддержка phpBB

 

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 6608306, ICQ 232284597
Пресс-релизы — pr@citforum.ru
Послать комментарий
Информация для авторов
This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2006 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...