| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > What is wrong in C++? |
| Автор: alex22222 21.11.2004, 20:33 |
| What is wrong in C++? Осваиваю язык С++ на MS VC++ 6.00 Win98. Написал простую программу для работы с указателями, однако она не работает. Что тут не так? Дебагер пишет ошибку: Access Violation Вот текст файла // TestLearnDlg.cpp : implementation file // #include "stdafx.h" #include "TestLearn.h" #include "TestLearnDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ……… void CTestLearnDlg::OnButtontest1() { char* mystr1; char* mystr2; mystr1 = "mytest"; L= strlen(mystr1); for (i =0; i<L; i++) { *mystr2 = *mystr1; *mystr2 = mytest; mystr2++; mystr1++; } Вроде бы все учебнику…. |
| Автор: sergejzr 21.11.2004, 20:39 |
| Ну да, весь код тут ошибка mystr2 не имеет своего места в памяти, а мы ему присваиваем значение *mystr2 = *mystr1; Скажите, что именно Вы собираетесь делать? И пожалуйста, пользуйтесь тэгами [code=cpp] [/code] |
| Автор: alex22222 21.11.2004, 21:37 |
| Я пытаюсь скопировать строку как указано в учебниках, а также в файле strcopy.c. Указатель mystr2 задан в памяти, поэтому нет проблем записать по этому адресу символ. Например в strcopy.c. выполняется копирование так *mystr2++=*mystr++; Но у меня опять ошибка - Access Violation ! Ваше предложение относительно тэгов я не понял, я пока только учусь. С большим удовольствием приму любую помощь. |
| Автор: sergejzr 21.11.2004, 21:56 | ||||||
Ок
Насколько я понимаю, желается следующее:
Вся конструкция однако заменяется (я бы так написал):
насчёт тэгов сверху есть кнопка КОД попробуйте вставить в свой пост: [code=cpp] #include "stdio.h" int main(){/*итд.*/} [/code] |
| Автор: alex22222 21.11.2004, 22:15 |
| Спасибо за хорошую вещь. Однако у меня остается смутное впечатление, что все таки я далек от понимания. Я хочу написать код не пользуясь функциями типа strlen. Опять же в файле strlen.c используется операция *p1=*p2. Почему у меня это не работает? Относительно вставки [code=cpp] и т.д. то в какой файл это нужно добавить? Я создал простой проект в MS VC, диалоговое окно с кнопкой OnButtontest1. При нажатии на эту кнопку я пытаюсь выполнить код. Как в фале strcopy.c. Еше раз прошу за дремучесть, но уж больно это все интересно. |
| Автор: manu 21.11.2004, 22:22 | ||
Сам говорил и сам же ошибсяЖ)))
|
| Автор: sergejzr 21.11.2004, 22:35 | ||
| Вставка [code] это в сообщение на форуме. Для того, чтобы код подсвечивался. А насчёт без strlen так это надо просто mystr2 памяти сразу побольше дать и 3-ий вариант использовать
Нет нет, абсолютно ничего страшного PS: manu, спасибо |
| Автор: Guest 21.11.2004, 23:55 |
| А как все таки использовать тело функции strcopy or strrev напрямую, как это делается в файлах strcopy.с or strrev.с. Почему код типа *p2=*p1 не выполняется у меня. char* mystr1; char* mystr2; mystr1 = "mytest"; mystr2 = "notest"; while(*mystr2++=*mystr1++); тут опять ошибка - Access Violation ! Что не правильно? |
| Автор: bel_nikita 22.11.2004, 00:00 | ||||
переключись в релиз версию
|
| Автор: Гость_alex22222 22.11.2004, 00:14 |
| Не работает! |
| Автор: sergejzr 22.11.2004, 00:17 | ||||
По вопросу.
-------------------------------------------- Кстати while(*mystr2++=*mystr1++); Это bel_nikita написал первым (не хочу плагиатить И ещё кстати, bel_nikita, опять ты с константными строками балуешься Как же релиз потом дебагить? Добавлено @ 00:20 Вот это вставьте в функцию и всё будет прекрасно работать
|
| Автор: bel_nikita 22.11.2004, 00:39 | ||||||
| Guest Последуйте совету sergej.z, заверните свой код в функцию. Вот, 100% рабочий пример:
|
| Автор: alex22222 22.11.2004, 00:43 |
| Уважаемые специалисты! Прошу прощения за дремучесть еще раз. Проблема вот в чем. Я создаю проект в MS VC++, диалоговое окно, с кнопкой Buttontest1. затем я беру тело функции strcopy, please look at source strcopy.c. затем я пытаюсь выполнить код void CTestLearnDlg::OnButtontest1() { char* mystr1; char* mystr2; mystr1 = "mytest"; mystr2 = "notest"; while(*mystr2++=*mystr1++); } Все инициализировано! Однако ошибка - Access Violation ! Я не хочу использовать стандартные функции типа strlen. Я просто повторяю код из функции strcopy! тут нет функции типа main() {} ЭТО MFC! |
| Автор: sergejzr 22.11.2004, 00:50 | ||||||
Разве в стандартной strcpy такое есть?
Это не важно
Вот рабочий вариант ------------------------- bel_nikita да я имею ввиду, что в дебаге с таким извращением работать невозможно. То, что скомпиленая верся "пропускает" кучу ошибок я не спорю |
| Автор: bel_nikita 22.11.2004, 00:53 | ||
alex22222
|
| Автор: JackYF 22.11.2004, 00:54 | ||||||
| Люди, как вы не поймете! нельзя использовать конструкцию типа:
можно только так:
Кажется, что отличия минимальны, но первый вариант принципиально неправильный потому что используется ПРИСВАИВАНИЕ, а второй - правильный, потому что компилятор переделывает такую запись приблизительно в
|
| Автор: sergejzr 22.11.2004, 00:58 |
| Какая разница в этом случае? Кроме конечно "лишнего" присваивания? |
| Автор: bel_nikita 22.11.2004, 01:04 | ||||
sergej.z
Вот, теперь я замуровал, так, что никто не доберется |
| Автор: sergejzr 22.11.2004, 01:09 |
| bel_nikita, неа, не убедил По умолчанию должно быть замуровано. А если надо, то можно и руками размуровать Но помоему это дело вкуса Так что каждый при своём останется. Но всё равно было очень интересно. Жму руку |
| Автор: bel_nikita 22.11.2004, 01:13 | ||||||||
JackYF
Неа, можно Вот, код:
давайте посмотрим, что творит компилер:
Так, в чем разница? Добавлено @ 01:18 sergej.z неа, а зачем тогда вообще const? как раз для таких случаев
|
| Автор: alex22222 22.11.2004, 01:36 |
| /*** *strncpy.c - copy at most n characters of string * * Copyright © 1985-1997, Microsoft Corporation. All rights reserved. * *Purpose: * defines strncpy() - copy at most n characters of string * *******************************************************************************/ #include <cruntime.h> #include <string.h> /*** *char *strncpy(dest, source, count) - copy at most n characters * *Purpose: * Copies count characters from the source string to the * destination. If count is less than the length of source, * NO NULL CHARACTER is put onto the end of the copied string. * If count is greater than the length of sources, dest is padded * with null characters to length count. * * *Entry: * char *dest - pointer to destination * char *source - source string for copy * unsigned count - max number of characters to copy * *Exit: * returns dest * *Exceptions: * *******************************************************************************/ char * __cdecl strncpy ( char * dest, const char * source, size_t count ) { char *start = dest; while (count && (*dest++ = *source++)) /* copy string */ count--; if (count) /* pad out with zeroes */ while (--count) *dest++ = '\0'; return(start); } Уважаемые специалисты! Я посылаю исходных код функции strcpy в MS Пожалуйста, не приплетайте сюда const! Иначе пришлю исходный текст strrev.c!!!! Почему не работает этот код void CTestLearnDlg::OnButtontest1() { char* mystr1; char* mystr2; mystr1 = "mytest"; mystr2 = "notest"; while(*mystr2++=*mystr1++); } Прошу вас не искать обходные пути, смотрите на исходный текст MS. Почему он работает, когда я вызываю функцию strcpy, а мой нет! Cordially начинающий программист Alex |
| Автор: bel_nikita 22.11.2004, 02:06 | ||
| alex22222 Чуть было монитор не разбил Еще раз привожу код:
|
| Автор: sergejzr 22.11.2004, 02:12 |
| Мда.а.а ну попробуем тоже ещё раз с другой перспективы... Строка mystr2 (не побоюсь этого слова) константна для Вижуала. Вы не можете изменять значения константной строки! или Компилируйте в Release.. Тогда Вижуал не будет это проверять |
| Автор: bel_nikita 22.11.2004, 02:18 | ||||
| sergej.z да не, просто надо в функцию завернуть. Вот, рабочий код в дебаг версии:
А вот, если сделаю так, то получу по рукам:
З.Ы.: все! я спасть. завтра на работу, однако... З.Ы.2: тьфу! сегодня |
| Автор: sergejzr 22.11.2004, 02:22 |
| Дык ведь он спрашивает, почему его код не работает |
| Автор: alex22222 22.11.2004, 02:33 |
| Уважаемые специалисты! Опять я повторяю, я не хочу пользоваться стандартными фукциями типа copy and etc. Я просто пытаюсь проверить код тела функции strcpy, а она не работает! Идет ошибка в присваивании *string1++ = *string1++; Иду простым путем, повторяю примеры и пытаюсь использовать исходные тексты MS, а они не работают! Попытки "Компилируйте в Release.. " - это уход от темы и проблемы! Помогите !!!!!!!!!!!!!!!!!! |
| Автор: sergejzr 22.11.2004, 02:38 | ||
Поэтому он иругается. то есть mystr2="чего нибудь"; надо заменить на mystr2=new char[512]; И тогда mystr2 не будет константной и колпилятор ругаться не будет. |
| Автор: alex22222 22.11.2004, 03:52 |
| Эта конструкция мне понятна. Мне не понятно, почему нельзя делать *string2++ = *string1++; для примера попробуйте так: *string1++ = *string1++; опять ошибка! Хотя при вызове стандартной функции strcpy, исходный текст которой я привел, все ОК. Значит ошибка слева от = *string1++; !!!!! Может быть надо включить какой ни будь режим типа pragma# когда в режиме MFC, подобные вещи начинают правильно работать? |
| Автор: sergejzr 22.11.2004, 04:06 | ||||
потому что string2 константна, а Вы ей значения присваиваете. А в стандартную strcpy если Вы два константных стринга передадите, тоже будет виолейшен. Попробуйте написать что нибудь типа:
Точно так же будет виолейшен. ПС: Если Вам надоели мои ответы, скажите просто |
| Автор: alex22222 22.11.2004, 17:49 |
| Да это правда. Однако почему mystr2 рассматривается как константный указатель, остается вопросом. Ведь явно он не был так определен! С оператором new все идет нормально. |
| Автор: shedon 22.11.2004, 18:17 | ||||
это неправильно, над так: char mystr1[]="abcde"; Просто попробуйте соед. код:
|
| Автор: !Жека! 27.11.2004, 08:44 | ||||||||
Все очень просто. Ты объявляеш указатель:
При этом компилятор не выделяет ни какой памяти, он просто запоминает имя и тип переменной. Этот указатель не начто не указывает - так. Далее ты пишеш:
Здесь компилятор делает небольшую хитрость он выделяет память и иницилизирует ее строкой "asdfghjkl". Т.е. он выполняет все так как если бы ты написал:
Понял |
| Автор: bel_nikita 27.11.2004, 21:25 | ||
!Жека!
Какой же это константный указатель, коли там const нет? |
| Автор: sergejzr 27.11.2004, 21:51 |
| Условно - константный. Или константный для дибагера Подойдёт? |
| Автор: !Жека! 27.11.2004, 22:36 | ||||||||
Путь ты и
Хотя все это зависит от среды программирования и настроек. Вот уменя такой фокус не прошел с выделением и памяти. пришлось писать так:
При этом если ты напишеш так:
то тоже получиш ошибку, а почему - догадайся. А вообще выкинь тот учебник в котором ты взял такой пример. Это плохой пример или перечитай заново эту статью может что и упустил.[s] |
| Автор: sergejzr 27.11.2004, 22:45 | ||
А ты в релиз скомпиль, ошибка пропадёт Это вечный спор и мы его с Никитой уже долго вели При этом каждый при своём остаётся ПС: !Жека!, тоже CTRL+S 'ом пытаешься мессагу отправить? |
| Автор: !Жека! 27.11.2004, 22:56 | ||
Да!!! Ну и на этом закончим!!! |
| Автор: Волод 27.11.2004, 23:46 | ||
| Прошу прощения, что вмешиваюсь, но меня заинтересовало начало кода с выделением памяти под указатель *mystr2. Как я понял, мы "разносим" указатели в пространстве, выделяя под каждый из них свой блок памяти. А как сделать так, чтобы оба указателя ссылались на один блок? Если это нельзя сделать через *mystr2 = *mystr1; - тогда как? И второй вопрос по циклу:
ЧТо здесь является признаком окончания цикла? Если это выражение при очередном присвоении возвращает ложь, то как и почему? - как здесь происходит контроль выхода за пределы массива? |
| Автор: bel_nikita 28.11.2004, 01:12 | ||||||||||||||||||||||||||||
shedon
Пробывал, в релиз MSVC6 !Жека!
Вот, константный указатель:
так, что char* p = "dfjd"; - никакой не константный указатель. Волод
По другому это выглядит так:
Вернемся к нашей проблеме. sergej.z
А проблема, то что в дебаг не работает, а в релиз работает - это все в распеределении памяти Вот, простенький примерчик:
Запустите его в дебаг, потом в релиз. И внимательно посмотрите на то, что выпишет printf. Запишите адреса на бумажку. Потом для укрепления теории
Я так понимаю, делается это дебагером специально, чтобы в релиз при оптимизации не возникали проблемы. Кстати, в MSVC 7.1 выдает экзепшен как в дебаг, так и в релиз. Там, немного по другому память выделяется З.Ы.: кому интересно отличие char*p от char p[] читаемhttp://www.rsdn.ru/Forum/?mid=177690. Потом запускам дебаг режим и смотрим, что компилятор генерит в этих случаях. |
| Автор: sergejzr 28.11.2004, 01:32 | ||||
Я всё же попытаюсь коротко ответить на сам вопрос Волод 'а
оператор * - содержимое указателя. В этом случае то же, что и [0]. То есть *mystr2 == mystr2[0] Чтобы указатель показывал на другой участок памяти делаем просто: mystr2 = mystr1 ------------------
вот когда содержимое указателя mystr1 станет 0. цикл и остановится |
| Автор: Guest 28.11.2004, 18:02 |
| sergej.z, спасибо. Ведь знал, что после обьявления указателя обращение к нему идет без оператора*- и вот надо же, стал читать чужой листинг и запарил. |
| Автор: sergejzr 28.11.2004, 18:10 |
| Не проблема ПС: Добро пожаловать к нам на форум! |