![]() |
Внимание, важное сообщение: Дорогие Друзья!
В ноябре далекого 2001 года мы решили создать сайт и форум, которые смогут помочь как начинающим, так и продвинутым пользователям разобраться в операционных системах. В 2004-2006г наш проект был одним из самых крупных ИТ ресурсов в рунете, на пике нас посещало более 300 000 человек в день! Наша документация по службам Windows и автоматической установке помогла огромному количеству пользователей и сисадминов. Мы с уверенностью можем сказать, что внесли большой вклад в развитие ИТ сообщества рунета. Но... время меняются, приоритеты тоже. И, к сожалению, пришло время сказать До встречи! После долгих дискуссий было принято решение закрыть наш проект. 1 августа форум переводится в режим Только чтение, а в начале сентября мы переведем рубильник в положение Выключен Огромное спасибо за эти 24 года, это было незабываемое приключение. Сказать спасибо и поделиться своей историей можно в данной теме. С уважением, ваш призрачный админ, BigMac... |
Строки в С\С++
|
Новый участник Сообщения: 39 |
При программировании строк в Visual C++ и под Linux я заметил такую штуку:
Если обявить строку как char* pch = "Some_string" то операция *pch = 'A' приводит к ошибкам выполнения. В Linux пишет Segmentation Fail т.е. ошибка обращения к памяти. И в тоже время объявление char pch[] = "Some_string" и операция *pch = 'A' отрабатывает нормально без всяких глюков. Может кто знает где здесь собака зарыта. Только если можно поподробнее. Я думаю это как-то связано с защитой памяти в ОС или что-то в этом духе |
|
Отправлено: 23:13, 05-04-2003 |
Старожил Сообщения: 163
|
Профиль | Отправить PM | Цитировать Раз вы так все хорошо со строками ориентируетесь, то объясните такую вещь:
Visual C++ С помощью CListCtrl создаю свой собственный класс списка (использую пример, естественно), где каждый элемент списка представляет собой кнопку. Для отрисовки строк используется процедура DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { ... dc.DrawTedxt((LPCTSTR)lpDrawItemStruct->itemData,rect, * *DT_LEFT | DT_WORKBREAK); dc.Detach(); } //Строки добавляем сюда m_List.AddString(_T("Some String")); CString str="Some String"; m_List.AddString(str); * на экране галиматья, т.е. любое использование локальных для данной процедуры переменных приводит к тому, что данные не отображаются. если использовать char str=new char[20]; ... то все отображается, но при попытке delete str[] все накрывается, потому что список использует эти значения Итог такой работает только если самостоятельно плодить утечку памяти, где ж это все хранится? сама функция DrawItem использует не адрес а число, адрес содержащее, и в чем загвоздка не пойму [s]Исправлено: Crew, 23:14 7-04-2003[/s] |
------- Отправлено: 23:12, 07-04-2003 | #11 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Новый участник Сообщения: 39
|
Профиль | Отправить PM | Цитировать Crew
> Или вопрос был где именно хранится значение переменной? Да вопрос как раз в этом то и заключался, то что будут ошибки так это я сам знаю. Почему? ruslandh А что по вашему должна делать команда *pch='A' ? - записать по адресу, указанному в pch значение 'A' ? Т.е по адресу 0x00129 записать 0x100 ? Фишка в том что *pch - разименование указателя. Т.е. 'A' будет записано в ячейку, адрес которой содержится в pch. Vaulter Так если объявление char* pch = "Some_String"; не выделяет память то куда же она будет записана. Ведь вывести я ее могу? |
Отправлено: 14:32, 08-04-2003 | #12 |
Пользователь Сообщения: 65
|
Профиль | Сайт | Отправить PM | Цитировать VBMUSTDIE
освободить то ее надо потом ) хотя это будут Memory leaks |
Отправлено: 22:23, 08-04-2003 | #13 |
Новый участник Сообщения: 39
|
Профиль | Отправить PM | Цитировать Знаете в чем еще фишка. Если сделать Active Confoguration не Debug а Release все работает. Вообще какая-то фигня
![]() |
Отправлено: 23:09, 08-04-2003 | #14 |
Пользователь Сообщения: 65
|
Профиль | Сайт | Отправить PM | Цитировать VBMUSTDIE
в Debug режиме, VC запускает прогу в своей куче. |
Отправлено: 02:01, 09-04-2003 | #15 |
Модер Сообщения: 1716
|
Профиль | Сайт | Отправить PM | Цитировать Crew
Меня очень ломает разбираться в MFC, потому давайте вместе. Какие прототипы есть у вызова AddString? То есть, что можно передать этой функции (без учета приведения типа непосредственно внутри скобочек)? Есть мысль, что AddString просто берет указатель на строку, если у тебя строчка в сегменте данных, то работать будет, если через CString - то ты отдаешь в лист указатель на CString-овую строку - при прибитии его тебе программа вполне обосновано дает по рукам, так как адрес, сохраненный в твоем листе, уже толком никуда не указывает. Аналогично и с массивом, пока не убьешь его, все будет работать. Vaulter Цитата:
Я собрал проект как Debug. Закрыл к чертям MSVC. Запустил собранный проект. Откуда он возьмет кучу MSVC? |
|
------- Отправлено: 02:40, 09-04-2003 | #16 |
![]() Старожил Сообщения: 240
|
Профиль | Отправить PM | Цитировать Vaulter
Когда я выше упоминал, что к выделению памяти этот случай не имеет отношения, я имел ввиду динамическое выделение памяти. Слово "динамическое" я опустил, за что справедливо получил по шапке от vasketsov-а. Так вот, если память выделяется динамически с помощью всяких там new, malloc и им подобных, то память нужно освобождать, а если (как написано) , то за это отвечает компилятор и об освобождении беспокоиться не нужно. |
------- Отправлено: 12:51, 09-04-2003 | #17 |
Пользователь Сообщения: 65
|
Профиль | Сайт | Отправить PM | Цитировать VBMUSTDIE
скажу всетаки секрет один: char* a="something"; "а" вообще то будет распознана компилятором как строковая константа: const char a[9]; поэтому и нельзя a[4]='a'; а вот char a[]="something"; можно. потому как будет "а" будет как char a[9]; |
Отправлено: 14:13, 09-04-2003 | #18 |
Старожил Сообщения: 163
|
Профиль | Отправить PM | Цитировать vasketsov
AddString может принимать как CString, так и char * функция прорисовки в любом случае получает только DWORD, вытаскивать что там такое моя задача (несложная) Я трейсером смотрел все она передает, но только почему-то (трейсер не улавливает) перерисовывает эти данные не один раз а три. Но ладно бы так как я делаю, но я удалить не могу эти строки (которые создаю), иначе на экран выводится "ЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭЭ" причем удалить не могу ни до, ни после отрисовки, потому-что она еще раз вызывается. и если я удаляю после AddString, оно понятно почему накрывается. А если в DrawItem(...) * *const char*s=_T(LPCTSTR(lpDrawItemStruct->itemData)); * *dc.DrawText(s), rect, * *DT_LEFT | DT_WORDBREAK); * *dc.Detach(); * *delete s[]; Vaulter Цитирую из книги "Программирование на VC++ 6.0" серия для профессионалов Чтобы константы гарантированно хранились вместе с программой, придется немного поработать. Во превых, обратите внимание на строковые константы, которыми часто изобилуют программы. Может, Вы решили, что они будут данными "только для чтения"? Тогда попробуйте угадать еще раз. Действительно, поскольку Вы имеете право написать что-нибудь вроде "test" не может быть константой. Чтобы строка стала константой, ее надо соответствующим образом *объявить и инициализировать, например, так: Теперь g_pch хранится вместе с кодом. Но где именно?Чтобы ответить на этот вопрос, надо знать о секциях данных (data session), генерируемых компоновщиком Visual С++. ... Имя * * *Тип * * * * * Доступ * * * * * * * * * * Содержимое .text * * код * * * * * *только чтение * * * * *код программы .rdata * данные * * только чтение * * * * *инициализированные константы .data * *данные * * *чтение и запись * * *инициализированные данные (не кон) .bss * * данные * * * чтение и запись * * неинициализ данные (не кон) Секция .rdata - часть EXE файла, именно сюда компоновщик поместит переменную g_pch. Из всего вышесказанного становится непонятно почему не работает код, ставшей причиной этого топика ![]() [s]Исправлено: Crew, 0:04 10-04-2003[/s] |
------- Отправлено: 23:51, 09-04-2003 | #19 |
Модер Сообщения: 1716
|
Профиль | Сайт | Отправить PM | Цитировать Цитата:
Пример 1. Цитата:
Пример 2. Цитата:
Про то, что xx[] на стеке будет, можно даже не говорить. Если нет - стековый параметр суется в секцию данных - это просто ужас, такие компиляторы если и есть в природе, они абсолютно не жизнеспособны. А вот "test" может быть как в стеке (прямо здесь же, зачем ее иметь в других местах?), а может быть и в секции данных (если "test" много и компилятор решил заняться оптимизацией). Crew Попробуй сделать так void addx(идентификация листа, напр., указатель на него) { char x[8] = "йцукен"; x[0]='q'; //чтоб не оптимизировалось твой Add(x) } [/code] если вылетит - придется либо глобальные строчки использовать, либо руками память выделять/освобождать (освобождать можно при наступлении события удаления элемента, вроде там такое есть, по крайней мере винда такое сообщение шлет). |
|||
------- Отправлено: 09:02, 10-04-2003 | #20 |
![]() |
Участник сейчас на форуме |
![]() |
Участник вне форума |
![]() |
Автор темы |
![]() |
Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
Интерфейс - Трей в 2 строки | .ExeRun | Microsoft Windows 7 | 2 | 31-12-2010 01:22 | |
.NET - перечисляемые строки | Surround | Программирование и базы данных | 3 | 05-10-2009 19:57 | |
MySQL - Автозамена строки из другой строки - trigger? procedure ? | BugZZ | Программирование и базы данных | 0 | 18-09-2009 09:51 | |
строки в С++ | rodman | Программирование и базы данных | 7 | 02-07-2004 12:54 |
|