| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Для новичков > копирование указателей |
| Автор: grisWall 6.9.2013, 11:49 | ||||||
Всем доброго времени суток у меня назрел вопрос. Я решил тут на днях написать программку на Си которая принимает в консоли параметры и создает папку с именем и помещает в неё main.c. Что то типа начальный шаблон для автоматизации создания программ в отдельных папках, а то я тут глянул один раз и ужаснулся что у меня в одной папке столько программ и столько хлама что в пору уже вешаться чем со всем этим разобраться. Я решил написать программку и вроде написал я ее и она мне все создавала. Но вот не задача решил, я начитавшись K&R переписать её указателями. И тут я попал на такую вещь как ошибка сигментирования я то ее реализовал массивами и горя не знал а вот как только я начал делать
и дальше хуже кто-нибудь объясните мне, почему вот такой код вызывает ошибку сигментирования?
при том что все это компилируется молча. |
| Автор: leshiysoft 6.9.2013, 11:58 |
| Если просто, то так: Потому что в Ваше переменной file лежит указатель на константную строку в сегменте данных, так как вы её задаете прямо в коде. Други словами в куче место под эту переменную не выделялось и аллоков и маллоков небыло. Вот она и ругается, мол, в сегмент данных, содержимое которого формируется в процессе компиляции, нехорошо писать. Нужно руками выделять необходимый объем памяти. |
| Автор: grisWall 6.9.2013, 12:08 |
а если по конкретнее? |
| Автор: leshiysoft 6.9.2013, 13:41 | ||||||||
Правильно так:
Все дело в том, что любая строка в кавычках используемая в коде - это const char*, причем располагается она в секторе данных для чтения. Следовательно, записывать в неё нельзя. Для записи нужно вручную выделить память, например, так:
и незабыть очистить память:
Кстати можно было не вводить новую переменную fileName и использовать строку в кавычках прямо в аргументах функции strcpy:
так как она (строка в кавычках) имеет нужный для strcpy тип : const char* |
| Автор: feodorv 6.9.2013, 13:44 | ||||||
Переменная file указывает на область в памяти процесса, в которой находятся символы '\t', ' ' ... ' ', '*', '\0' Проблема в том, что эта область памяти защищена от записи. Так её создал и определил компилятор, что вполне корректно, ибо строковый литерал по своей сути - константа. Более того, если Вы создадите ещё одну подобную переменную, указывающую на ту же самую строку:
Что делать? Самый простой способ - это воспользоваться инициализированным массивом:
Добавлено через 2 минуты и 17 секунд А без выделения памяти никак??? Добавлено через 5 минут и 30 секунд Да, нужно заметить, что эта изменяемая память ограничена в размерах - 100 байт и не более. В случае выхода за её пределы:
|
| Автор: leshiysoft 6.9.2013, 13:50 |
| Массив действительно подойдет, так как массив в С - это ничто иное как указатель. И память выделенную под массив не нужно очищать. Но в случае если размера массива вам будет нехватать надо будет переписывать и перекомпилировать программу. Особенно это неприятно и неправильно, когда необходимый размер под строку заранее неизвестен, например, зависит от размера строки введенной пользователем. |
| Автор: grisWall 6.9.2013, 23:23 | ||||
да я кстати замечу что у меня то в коде изначально я реализовал массивами все это дело вот так:
это я уже для эксперименту решил по пробовать получиться может изящнее или эффективнее вот и напробовался блин так что мама не горюй щас все вернул назад даже что-то доработал в старой версии. Так что всем спасибо за дельные советы все очень помогли особенно с malloc и free а по поводу определения размера у массива я тоже взял на заметку... спасибо.
|
| Автор: akizelokro 7.9.2013, 10:49 |
Смотри, есть системные требования, например, для максимальной длины названия файла (вместе с путём). Вердикт. Массиву сразу присваешь такую размерность. Не экономь сотню байтов, зато потом ты лишний раз нигде не будешь удивлятьс. Это раз. |
| Автор: feodorv 7.9.2013, 11:43 | ||||||
Ну, тут немного другие требования. Готовится вывод на экран в "красивом" виде))) Следовательно, нужно не увеличивать буфер под возможности файловой системы, а ограничить длину имени файла:
Кстати:
48 байт явно мало для строки "\t* *" |
| Автор: ТарасАтавин 7.9.2013, 12:26 | ||
|
| Автор: akizelokro 7.9.2013, 12:49 |
| Руку на чем-то набивать ему надо |
| Автор: ТарасАтавин 7.9.2013, 13:34 | ||
|