Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
Всем привет. Не могу разобраться, как правильно работать с strcat. Пишу такое, и получаю ошибку: Код: plaintext 1. 2. 3. Что делаю неправильно? [strcat] возвращает указатель, я его значение присваиваю другому указателю. Это как вот такое сделать: Код: plaintext 1. 2. 3. Так все работает. Заранее спасибо за помощь! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.11.2012, 23:58 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
MaximuS_G, Кто память будет выделять? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 00:10 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
MaximuS_GВсем привет. Не могу разобраться, как правильно работать с strcat. Пишу такое, и получаю ошибку: Код: plaintext 1. 2. 3. Что делаю неправильно? Строка: char *myString = "hello"; Означает: Выделить в памяти принадлежащей сегменту кода кусочек в шесть байт, записать туда пять букв h, e, l, l, o и закончить нулем. После этого выделить на стеке кусочек памяти размером в адрес и записать в эту память адрес первого куска. char *stringResult; Означает: Выделить на стеке кусочек памяти размером в адрес, ничего туда не писать. stringResult = strcat(myString,"as"); Означает: Найти в первом куске памяти (который длиной шесть байт) нулевой байт. Записать на место этого нулевого байта букву a, потом в следующий байт записать букву s, потом записать ноль. Потом записать адрес первого куска памяти в третий. А если теперь внимательно подумать, мы сможем заметить что когда в самом начале мы выделяли первый кусок в шесть байт размером мы не оговаривали что будет находится после него. Соотвественно когда мы пишем седьмую букву s эта буква попадает в неизвестно куда с неизвестно какими последствиями. Вариантов последствий очень много, и все они зависят от конкретной OS в которой ты пытаешься это сделать, компилятора который ты используешь и даже настроек этого компилятора. В некоторых случаях это может даже работать и ты ничего не заметишь. Но к счастью, в данном случае ты "получил ошибку", рискну предположить что это "попытка записи в сегмент для чтения", так? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 00:16 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
Westtrd Спасибо за подсказку. Но ведь во втором примере не выделяется память? Или в первом примере нужно выделять память под "hello", и под "helloas"? Ну так я тоже получаю ошибку: Код: plaintext 1. 2. 3. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 00:21 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
White Owlрискну предположить что это "попытка записи в сегмент для чтения", так? Если у него достаточно свежий компилятор, то это скорее сообщение о несовместимости char* и const char* ещё при компиляции. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 00:24 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
MaximuS_G Westtrd Спасибо за подсказку. Но ведь во втором примере не выделяется память? Или в первом примере нужно выделять память под "hello", и под "helloas"? Ну так я тоже получаю ошибку: Код: plaintext 1. 2. 3. А так, память которую ты выделил во второй строке просто теряется. В третей строке ты перенаправляешь указатель на "hello" а те десять байт остаются висеть всеми забытыми. Ты их теперь даже освободить не можешь, потому что не знаешь где они находятся. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 00:26 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
Ошибка такая Unhandled exception at 0x0f74d32a in 17.11.exe: 0xC0000005: Access violation writing location 0x0020bc71. White Owl Спасибо за подробно расписанное объяснение. Но постом выше я привел кусок кода, где я выделяю память, но все равно получаю ошибку. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 00:26 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
White OwlMaximuS_G Westtrd Спасибо за подсказку. Но ведь во втором примере не выделяется память? Или в первом примере нужно выделять память под "hello", и под "helloas"? Ну так я тоже получаю ошибку: Код: plaintext 1. 2. 3. А так, память которую ты выделил во второй строке просто теряется. В третей строке ты перенаправляешь указатель на "hello" а те десять байт остаются висеть всеми забытыми. Ты их теперь даже освободить не можешь, потому что не знаешь где они находятся. Так а как правильно сделать? :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 00:31 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
MaximuS_GОшибка такая Unhandled exception at 0x0f74d32a in 17.11.exe: 0xC0000005: Access violation writing location 0x0020bc71. White Owl Спасибо за подробно расписанное объяснение. Но постом выше я привел кусок кода, где я выделяю память, но все равно получаю ошибку.Ты не понимаешь смысла strcat(). Эта функция не манипулирует строками. Она их не копирует, и не переносит. Она берет два указателя. Сначала она двигает первый указатель до тех пор пока он не покажет на ячейку памяти в которой записан ноль. После этого она начнет двигать оба указателя разом и копировать байтик из ячейкие на которой показывает второй указатель в ячейку на которую показывает первый, до тех пока второй указатель не покажет на ячейку с нулем. После этого strcat() вернет копию первого указателя каким он был в самом начале. Так понятно? И вообще, разберись пожалуйста на каком языке ты пишешь. На C или C++? Не надо их смешивать, они хоть и похожие, но все-же разные. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 00:33 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
MaximuS_GWhite Owlпропущено... А так, память которую ты выделил во второй строке просто теряется. В третей строке ты перенаправляешь указатель на "hello" а те десять байт остаются висеть всеми забытыми. Ты их теперь даже освободить не можешь, потому что не знаешь где они находятся. Так а как правильно сделать? :)А вот это ты должен сам догадаться. Мы можем пояснять некоторые непонятные моменты, но если мы сделаем за тебя такую элементарную задачу - нам придется за тебя и диплом и зарплату получать. А ты ж наверное сам хочешь и диплом и зарплату? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 00:36 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
White Owl White Owl...Так понятно? Спасибо, это понял. Но не пойму тогда что здесь не так: Код: plaintext 1. 2. 3. Под myString выделено 9 байт. "\0" функция найдет, и после него еще есть место, куда приделать "as". Что не нравиться с++? :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 00:47 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
MaximuS_G White Owl White Owl...Так понятно? Спасибо, это понял. Но не пойму тогда что здесь не так: Код: plaintext 1. 2. 3. Под myString выделено 9 байт. "\0" функция найдет, и после него еще есть место, куда приделать "as". Что не нравиться с++? :)С++ нравится все. А вот ОС нравится не все. Читай внимательнее мой первый пост. То где я говорил о "сегментах". Память она разная бывает. Бывает память на стеке, бывает на куче, бывает в сегменте данных, бывает в сегменте кода, бывает общая, бывает отображенная, много их... Вот только простой памяти не бывает. "Просто" память это из разряда беллетристики и киноляпов. Так вот "hello" (как и "as" и "hello\0111") записываются компилятором либо в сегмент кода, либо в сегмент данных, либо в сегмент константных данных. Это зависит от компилятора и его настроек. А ОС считает что сегменты кода и сегменты константных данных это сегменты только для чтения. Писать туда нельзя вообще, а тот кто туда пишет - злобный вирус и вообще враг всего доброго и светлого, а значит должен быть убит через Access violation. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 01:09 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
White Owl Наверное Вы правы, я не очень понимаю, зачем нужна эта функция, и поэтому пытаюсь что-то нагородить. Можете привести пример самый банальный использования этой функции? У меня следующая задача. Есть структура, и я хочу ее свойства записать в другое свойство через слеш: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. У меня задача получить в object1.compString такую строку "robocop/cameron" . Вот я и хотел объединить эти свойства с помощью функции strcat . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 18:57 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
MaximuS_G, Если вы уже используете С++ так используйте все его возможности Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. Или обоснуйте почему надо использовать именно С-шные строки (char*). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 19:26 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovsky Спасибо за подсказку. Я просто еще не учил класс string. Буду знать, что так можно, так конечно для моего восприятия легче - я на javascript пишу :). Но сейчас хочу разобраться как работать со строками как с массивом char, вдруг в будущем понадобиться. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. Подскажите, пожалуйста, а зачем Вы объявляете функцию main как такую, которая возвращает значение int? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 19:31 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
MaximuS_GПодскажите, пожалуйста, а зачем Вы объявляете функцию main как такую, которая возвращает значение int? Хотя многие компиляторы пропускают и void, но по стандарту положено int. (Возвращаемый из main код - это код выхода приложения, 0 - нормальный выход, не 0 - ошибка ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 19:42 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
MaximuS_G White Owl Наверное Вы правы, я не очень понимаю, зачем нужна эта функция, и поэтому пытаюсь что-то нагородить. Можете привести пример самый банальный использования этой функции? У меня следующая задача. Есть структура, и я хочу ее свойства записать в другое свойство через слеш: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. У меня задача получить в object1.compString такую строку "robocop/cameron" . Вот я и хотел объединить эти свойства с помощью функции strcat . На чистом C это так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. На С++ как у Anatoly Moskovsky. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 19:45 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyMaximuS_GПодскажите, пожалуйста, а зачем Вы объявляете функцию main как такую, которая возвращает значение int? Хотя многие компиляторы пропускают и void, но по стандарту положено int. (Возвращаемый из main код - это код выхода приложения, 0 - нормальный выход, не 0 - ошибка ) А параметры в скобках функции main по стандарту обязательны или там что угодно допускается? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 19:48 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
На чистом CНа чистом C это так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. Жуть! не надо так писать. Ошибка раз - помрет если строки movie и producer будут в сумме длиннее 50 символов. Ошибка два - чистить надо приемный буфер прежде чем что-то к нему приклеивать. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 20:10 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
На чистом CНа чистом C это так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. Спасибо за ответ. Вы тоже используете функци strcat , вот я не могу понять, почему у меня не получалось. Сейчас буду думать, чем мой вариант отличается. И у меня паралельный вопрос появился - вы создаете структуру и сразу определяете максимальное количество элементов в свойствах. Я создаю структуру с указателями, и потом в коде сколько мне понадобиться символов, столько я и создам, а потом скопирую указатель на массив. Чем такой подход плох? Спасибо! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 20:17 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
MaximuS_G Anatoly Moskovsky Спасибо за подсказку. Я просто еще не учил класс string. Буду знать, что так можно, так конечно для моего восприятия легче - я на javascript пишу :). Но сейчас хочу разобраться как работать со строками как с массивом char, вдруг в будущем понадобиться. Про строки как массив (С-строки). Первое что надо понимать, что "строка" это константа являющаяся массивом char. Даже если какие-то компиляторы и позволяют изменить эту константу - это баг (хотя в первую очередь это баг в ваше программе). Дальше. char* s - это не сама строка, а указатель на строку (массив char). Массив char (а значит и строку) можно присвоить в указатель, но при этом присваивается не сам массив, а указатель на его начало. Код: plaintext 1. 2. Дальше. Мы можем объявить явно массив char и присвоить ему строку/массив. В этом случае создается копия, котоая уже не константа. Код: plaintext 1. Чаще всего размер строки на этапе компиляции неизвестен, поэтому обычно такие массивы (их еще называют статическими, т.к. их размер вычисляется при компиляции и не может меняться при исполнении программы) не применяют, а применяют динамическое выделение памяти через new. Определяют размер строки через strlen, потом выделяют динамический массив через malloc(len +1 ) или new char[len + 1] (помним про завершающий 0, который не учитывается strlen), потом копируют strcpy. Для случая malloc, есть стандартная функция для всего процесса копирования - strdup. malloc/new возвращает указатель на созданный динамический массив. При этом если у нас два указателя, один на статический а другой на динамический массив, то компилятор никак не различает их. В обоих случаях это char*. Теперь важное. Память выделенную через malloc/new надо освобождать вручную через free/delete. А статический массив наоборот - не надо удалять. Но если мы имеем просто указатель, то мы не знаем это указатель на статический массив или динамический. И не можем принять решение удалять или нет. Тут есть два варианта. 1) - я его считаю неудачным и никогда не применяю - хранить в структуре вместе с указателем и флаг типа bool с признаком динамического массива (как наиболее тупая вариация - флаг не хранить а помнить что такое-то поле в структуре это динамический массив) 2) Всегда использовать динамические массивы когда в структуре данных хранятся указатели на строки. В случае если строка задана литералом "ааа" то копировать ее в динамический массив. Таким образом применяя все вышеперечисленное к последнему примеру получаем такое (так как речь все-таки про С, то используем С-шный malloc/free): Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 20:23 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
Тут была опечатка: strcpy в третьей строке должно быть strcat Код: plaintext 1. 2. 3. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 20:26 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
в скобках функции mainА параметры в скобках функции main по стандарту обязательны или там что угодно допускается? Их можно опускать справа налево. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 20:35 |
|
||
|
strcat - ошибка
|
|||
|---|---|---|---|
|
#18+
White OwlНа чистом CНа чистом C это так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. Жуть! не надо так писать. Ошибка раз - помрет если строки movie и producer будут в сумме длиннее 50 символов. Ошибка два - чистить надо приемный буфер прежде чем что-то к нему приклеивать. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. С динамической памятью кэш-промахов будет много. Да и выделение/освобождение помимо тормозов, не менее опасно забыть освободить память или обратиться к ранее освобожденной, чем выйти за пределы статического массива. А насчет чистки, согласен, но вполне достаточно \0 в конце каждой строки. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2012, 20:44 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=38042325&tid=2020661]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
182ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
57ms |
get tp. blocked users: |
1ms |
| others: | 15ms |
| total: | 298ms |

| 0 / 0 |
