Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RusFAQ.ru: Программирование на C / C++


Информационный Канал Subscribe.Ru


RusFAQ.ru: Программирование на C / C++

Выпуск № 286
от 17.06.2003, 02:20

Администратор:
Имя: Nick.Box
URL: Информационный ресурс
ICQ: 365124
[censored], [censored]
О рассылке:
Задано вопросов: 869
Отправлено ответов: 2022
Активность: 232.6 %
[Задать вопрос >>][Регистрация эксперта >>]
[Поиск в базе][Обсудить на форуме]


 Список экспертов, ответы которых опубликованы в данном выпуске

BOLT
Статус: Профессиональный
Общий рейтинг: 172.83
URL: Начинающему программитсу: софт, примеры, документация, Assembler, C/C++.
[Подробней >>]
Yuri Gordienko
Статус: Опытный
Общий рейтинг: 116.08
[Подробней >>]
baldr
Статус: Профессиональный
Общий рейтинг: 112.3
URL: Сайт об ОС DOS. Всем, кто любит эту ОС!
[Подробней >>]
 
Hayk
Статус: Доверительный
Общий рейтинг: 112.66
[Подробней >>]
vitya
Статус: Профессиональный
Общий рейтинг: 108.18
[Подробней >>]
Vdr
Статус: Доверительный
Общий рейтинг: 112.68
[Подробней >>]
 
Avl2k
Статус: Опытный
Общий рейтинг: 125
[Подробней >>]


 Краткий перечень вопросов

Вопрос № 855. Текст: ...В языке С++ введена ещё одна возможность привеления типов, которую обеспечивает функционал... (ответов: 4)
Вопрос № 856. Взгляните на код в приложении. При выполнении происходит ошибка, пишется Debug Assertion Failed. Ну ... (ответов: 6)
Вопрос № 857. Умоляю дайте пример как создать на Вин32АПИ (компилятор VC++ 6)простейшее приложение, которое выводи... (ответов: 1)

Вопросов: 3, ответов: 11


 Вопрос № 855

Текст: ...В языке С++ введена ещё одна возможность привеления типов, которую обеспечивает функциональная форма преобразования типа: имя_типа(операнд). Используется, когда тип имеет простое(несоставное)обозначение: long(2) - внутреннее представление - 4 байта, double(2) - внутр. представ-ние - 8 байт. Недопустимо: unsigned long (2) // Ошибка !!! Двойка в скобках -
это число, тип которого устанавливается ? Почему unsigned long (2) - ошибка ? Прокомментируйте, пожалуйста. Кстати, пока писал вопрос, почти понял сам. Bob Johnson прав про значительную долю ответа в вопросе :))) ...



Вопрос отправлен: 13.06.2003, 10:56
Отправитель: Challenger

[Следующий вопрос >>] [Список вопросов]

Отвечает BOLT

Доброе время суток, Challenger!
Да, Bob Johnson, прав: ты сам сможешь найти ответ в своем вопросе: Используется, когда тип имеет простое(несоставное)обозначение...
Да прибудет с тобой Велика Сила!

Ответ отправлен: 13.06.2003, 23:04
Отправитель: BOLT


Отвечает Yuri Gordienko

Добрый день, Challenger!
Используй u_long(2).
Просто unsigned long(2) интерпретируется компилятором как функция long(2) с непонятной хренотенью "unsigned" перед названием функции.
Успехов

Ответ отправлен: 13.06.2003, 11:10
Отправитель: Yuri Gordienko


Отвечает baldr

Доброе время суток, Challenger!
Да, в скобках - пишется число, тип которого устанавливается. Или, наоборот, можно написать так:
(long)2 - это будет то же самое, что и long(2) . А unsigned long нельзя потому, что тут уже
два слова используются, а это уже некоторая неопределенность. В некоторых компиляторах
присутствует модификатор ulong вместо этого (вариант: ULONG).


Ответ отправлен: 13.06.2003, 23:07
Отправитель: baldr


Отвечает Hayk

Доброе время суток, Challenger!
В дополнение к прозвучавшим ответам прибавлю, что компилер MSVC 6.0 понимает этот трюк.

Ответ отправлен: 16.06.2003, 13:15
Отправитель: Hayk


 Вопрос № 856

Взгляните на код в приложении. При выполнении происходит ошибка, пишется Debug Assertion Failed. Ну я догадался второй delete i закомментировать (уже в приложении), всё прошло нормально. Почему нельзя ещё раз удалить высвобождённое место, потому что его уже нет ? :)) В книжке написано, всё будет нормально, просто вернётся NULL, хотя вероятно Виктор прав, книжка та писана для TС++ 3.x. А у меня MS C++ 6.0.


Приложение:


Вопрос отправлен: 13.06.2003, 11:22
Отправитель: Challenger

[Следующий вопрос >>] [Список вопросов]

Отвечает Yuri Gordienko

Доброе время суток, Challenger!
Работать с указателем после применения delete преступно, т.к. по этому адресу может быть что угодно. Повторный вызов delete к необнуленному указателю - это тоже преступление, т.к. так можно и винт форматнуть (образно говоря). Повторное вызов delete для обнуленного указателя допустим (т.к. delete проверяет указатель на равенство нулю), но выглядит до безобразия глупо!!!
Успехов


Ответ отправлен: 13.06.2003, 13:06
Отправитель: Yuri Gordienko


Отвечает BOLT

Доброе время суток, Challenger!
Ты сам ответил на свой вопрос.Вообще-то, если я не ошибаюсь, повторное высвобождение памяти чревато крахом ОС, т.к. указатель принимает случайное значение.Современный менеджеры памяти более "хитрые" и предупреждают об этой ошибке.
Да прибудет с тобой Велика Сила!

Ответ отправлен: 13.06.2003, 23:03
Отправитель: BOLT


Отвечает vitya

Добрый день, Challenger!
Память просто нельзя удалять два раза. Но например следующий код работает
int i = new int[5];
...
delete [] i;
i = NULL;
delete [] i;
delete i;
Так как нулевой указатель удалять можно.
Далее. В программе ошибки:
после того, как для переменной выделена память в первый раз ее никто не удаляет, а потом в ту же переменную снова выделяется память. Соответственно происходит утечка памяти.
3. после delete i - cout << *i; работать не должен и должен возбуждать исключение.


Ответ отправлен: 13.06.2003, 11:38
Отправитель: vitya


Отвечает baldr

Добрый день, Challenger!
Не знаю, что у тебя за книжка, но я тебе посоветую с указателями так не шутить...
Ты создаешь динамически переменную с указателем i, а потом перезаписываешь указатель уже
другим числом - надо сначала удалить предыдущее (delete). Причем, это ты делаешь неоднократно.
Это не есть хорошо, ибо возникают неосвобожденные элементы памяти. Под виндой, возможно, и
есть какой-нибудь garbage collector (или как он там...), но не факт. Короче, удаляй за собой мусор!
И далее - ошибка возникает, видимо, там где ты, после удаления элемента (delete) пытаешься вывести
его в поток (вывод *i в cout). Элемента уже нет и i, скорее всего, указывает на NULL. И
разыменовывать его нельзя. Так что надо удалять уже после вывода или выводить просто значение
указателя, а не разыменовывать его.
Также, полезно почаще делать проверку на NULL в разных частях программы (если она большая)
и присваивать указателю NULL принудительно после удаления его памяти с помощью delete - так
ты избавишь себя от кучи проблем в случае разного понимания текста программы тобою и
компилятором. :)


Ответ отправлен: 13.06.2003, 23:08
Отправитель: baldr


Отвечает Vdr

Добрый день, Challenger!
По идее, когда ты вызвал второй раз new, ты потерял память выделенную для него изначально. После delete память освободилась и считается, что указатель никуда не указывает, поэтому второй раз удалить его нельзя. Операции с i все еще возможны, потому, что это все таки переменная которая никуда ни делась.
Удачи!

Ответ отправлен: 16.06.2003, 10:45
Отправитель: Vdr


Отвечает Avl2k

Доброе время суток, Challenger!
По стандарту оператору delete надо передавать или указатель на объект, выделенный по new, или NULL. В противном случае (что и происходит, когда память уже освобождена и указатель "смотрит" на освобожденное место) поведение не определено (т.е. зависит от реализации, и завязываться на него ни в коем случае нельзя - для переносимости).
Вообще, повторное освобождение выделенной памяти говорит об ошибке в программе, поэтому в MSVC++ в debug'е и выдается сообщение об ошибке.
С уважением, Avl2k.

Ответ отправлен: 16.06.2003, 12:31
Отправитель: Avl2k


 Вопрос № 857

Умоляю дайте пример как создать на Вин32АПИ (компилятор VC++ 6)простейшее приложение, которое выводит два окна и не завершается, пока не закроют оба окна??? В книжке сказано, мол создайте два класса окна и не посылайте сообщение WM_QUIT, пока не закроются оба окна, но как это сделать??? Перепробовал кучу вариантов, но толку никакого (в приложении один из последних вариантов (абсолютно дурацкий, так как уже об стену головой бьюсь), при котором окна хоть и закрываются, но организовываем Ctrl+alt+del -> программа зависла...). Под Вин начал учиться писать буквально говоря вчера, и по крайней мере пока практически ничего в этом деле не понимаю (особенно со всякими сообщениями, вызовами обработчиков событий и тому подобного), а следовательно, очень хочется получить именно работоспособный пример.
Пожалуйстааааааааааааааааааааа.........................................


Приложение:


Вопрос отправлен: 13.06.2003, 17:47
Отправитель: Toilet (pooh@apexnet.com.ua)

[Следующий вопрос >>] [Список вопросов]

Отвечает BOLT

Добрый день, Toilet!
Вот см приложение.Твоя идея была верна, но реализовал ты ее чуть-чуть не правельно.
Да прибудет с тобой Велика Сила!
============================================================
#define WIN32_LEAN_AND_MEAN
#include
#include
int j=0, i=0;
LRESULT CALLBACK WindowProc1(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK WindowProc2(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
HWND hWnd1, hWnd2;
WNDCLASSEX windclass1, windclass2;
MSG msg;
windclass1.cbSize=sizeof(WNDCLASSEX);
windclass1.style="CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW;"
windclass1.lpfnWndProc=WindowProc1;
windclass1.cbClsExtra=0;
windclass1.cbWndExtra=0;
windclass1.hInstance=hInstance;
windclass1.hIcon=LoadIcon(NULL, IDI_APPLICATION);
windclass1.hCursor=LoadCursor(NULL, IDC_ARROW);
windclass1.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH);
windclass1.lpszMenuName=NULL;
windclass1.lpszClassName="WINDCLASS1";
windclass1.hIconSm=LoadIcon(NULL, IDI_APPLICATION);
windclass2.cbSize=sizeof(WNDCLASSEX);
windclass2.style="CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW;"
windclass2.lpfnWndProc=WindowProc2;
windclass2.cbClsExtra=0;
windclass2.cbWndExtra=0;
windclass2.hInstance=hInstance;
windclass2.hIcon=LoadIcon(NULL, IDI_APPLICATION);
windclass2.hCursor=LoadCursor(NULL, IDC_ARROW);
windclass2.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH);
windclass2.lpszMenuName=NULL;
windclass2.lpszClassName="WINDCLASS2";
windclass2.hIconSm=LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&windclass1)) return 0;
if(!RegisterClassEx(&windclass2)) return 0;
if(!(hWnd1=CreateWindowEx(NULL, "WINDCLASS1", "First window", WS_OVERLAPPEDWINDOW|WS_VISIBLE,
100, 200, 300, 300, NULL, NULL, hInstance, NULL))) return 0;
if(!(hWnd2=CreateWindowEx(NULL, "WINDCLASS2", "Second window", WS_OVERLAPPEDWINDOW|WS_VISIBLE,
500, 200, 300, 300, NULL, NULL, hInstance, NULL))) return 0;

for(;;)
{
if(PeekMessage(&msg, hWnd1, 0, 0, PM_REMOVE))
{
if(msg.message==WM_QUIT) break;
TranslateMessage(&msg);
DispatchMessage(&msg);

}

if(PeekMessage(&msg, hWnd2, 0, 0, PM_REMOVE))
{
if(msg.message==WM_QUIT) break;
TranslateMessage(&msg);
DispatchMessage(&msg);

}
/* Вот здесь изменил*/
if (i==1 && j==1) //если обе метки закрытия кона установлены, то останавливаем процесс
ExitProcess(0);
}
return msg.wParam;
}
LRESULT CALLBACK WindowProc1(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hDc;
switch(msg)
{
case WM_CREATE:
return 0;
case WM_PAINT:
hDc=BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
return 0;
case WM_DESTROY:
i=1;//устанавливаем метку закрытия окна1
return 0;
default:
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}

LRESULT CALLBACK WindowProc2(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hDc;
switch(msg)
{
case WM_CREATE:
return 0;
case WM_PAINT:
hDc=BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
return 0;
case WM_DESTROY:
j=1;//устанавливаем метку закрытия окна2
return 0;
default:
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
============================================================

Ответ отправлен: 13.06.2003, 23:03
Отправитель: BOLT



Форма отправки вопроса

Внимание!
Мы рекомендуем открывать рассылку в программе Internet Explorer 5.0+ или отправлять вопросы с сайта по адресу: http://rusfaq.ru/cgi-bin/Message.cgi.

(C) 2002-2003 Команда RusFAQ.ru.

 Персональные данные

Ваше имя:

Ваш e-mail:

Опубликовать мой e-mail в рассылке


 Вопрос и дополнение

Ваш вопрос:


Приложение (если необходимо):


Получить ответов:


 Выбор рассылки

Программисту
Assembler (38)
C / C++ (27)
Perl (5)
Builder / Delphi (17)
Pascal (29)
Basic / VBA (10)
Java / JavaScript (11)
PHP (5)
MySQL / MSSQL (6)
Пользователю
Windows 95/98/Me (32)
Windows NT/2000/XP (27)
"Железо" (19)
Поиск информации (13)
Администратору
Windows NT/2000/XP (13)
Linux / Unix (6)
Юристу
Гражданское право (7)
Семейное право (3)
Трудовое право (4)
КоАП (3)

Отправить вопрос всем экспертам выбранной рассылки.




Задать вопрос | Регистрация эксперта | Поиск в базе | Чат | Форумы | Новости
Проект экспертов RusFAQ.ru | Фотоальбом | Virus.RusFAQ.ru | Администрирование


Яндекс цитирования
© 2001-2003 Россия, Москва. Авторское право: Калашников О.А.

http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное