| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Для новичков > Вопрос про 2 мерные указатели |
| Автор: djezul 3.7.2009, 16:19 | ||
Вот код -
По нему есть несколько вопросов. 1 - что это за ошибка - http://ipicture.ru/ Какова причина её возникновения ? И как её исправить ? И почему , там где я поставил <<<<< удаляется и q , а не только p , как удалить только p ? Прога , думаю и так понятно , но всё же скажу , должна создавать динамический массив с возможностью добавления. С 1 мерными у меня всё работает , но так почему то нет . |
| Автор: zim22 3.7.2009, 16:24 |
скорей всего вы пишете либо за пределы массива либо удаляете статический массив. |
| Автор: djezul 3.7.2009, 16:39 |
| ну по коду должно быть видно , что массив не статический, и за пределы вроде не вылетаю, тем более пишет , что в 52 строке , причем здесь она, никак не пойму. |
| Автор: Albor 3.7.2009, 16:47 |
| При копировании массива (add()) копируются указатели p[i]=q[i]; затем массив q удаляется, соответственно все указатели массива p становятся недействительными. Копируя массив, копируй только содержимое, а указатели не трогай, в каждом массиве свои. |
| Автор: zim22 3.7.2009, 18:37 |
какого файла? не вашего. |
| Автор: djezul 3.7.2009, 23:27 |
В том то и дело , что этого) |
| Автор: Albor 4.7.2009, 06:14 | ||||
djezul, ты сам писал код? Если да, то должен понимать что написано. Что такое p[i] и q[i] - это указатели на char. Смотри, для q[i] ты делаешь следующее:
После этого q[i] указывает на область памяти, куда скопирована строка из surname. Дальше удаляется и вновь создаётся с новым размером массив p - нормально. Но дальше... что делает строка p[i]=q[i]? Ты просто копируешь указатель, после этого оба массива указывают на одни и те же данные, а строчка strcpy( p[i] , q[i] );? - посмотри в дебаге что ты копируешь и куда, указатели-то одинаковые, но это пол-беды (скажем даже не совсем беда, может у программера такой каприз
тогда p[i] уже не зависит от q[i]. |
| Автор: djezul 4.7.2009, 15:54 |
| Albor, спасибо , я врубился в это ещё после твоего 1 поста))) просто я ж говорю , при написании подобной проги только с 1 мерным массивом указетелей, так прокатывало , поэтому решил и тут так сделать) теперь понял , что это неправильно . Твой вариант работает , спасибо) P.S. код писал сам)) |
| Автор: zim22 4.7.2009, 16:00 |
new кидает exception, когда не может выделить память |
| Автор: djezul 4.7.2009, 16:17 |
| zim22, Спасибо , буду знать) |
| Автор: djezul 4.7.2009, 19:06 | ||
А как правильно сделать сортировку , мне нужно допустим по алфавиту отсортировать фамилии, вот я пытаюсь так
НО , так не работает , почемуто не хочет выделять достаточно памяти для p[i] , хотя я вроде еёудаляю , и создаю с необходимым количеством((( В чём тут ошибка? |
| Автор: zim22 4.7.2009, 19:19 |
используйте std::sort или qsort |
| Автор: djezul 4.7.2009, 20:27 |
| zim22, не просто хочу научится работе с указателями) то понятно. |
| Автор: zim22 4.7.2009, 20:57 |
почитайте тогда книгу Б.Кернигана, Д.Ритчи "Язык программирования С". Глава 5 "Указатели и массивы". |
| Автор: djezul 4.7.2009, 22:39 |
| zim22, Читал, и не только Б.Кернигана, Д.Ритчи , и Шилдта читал, но всё равно непонятно , почему не работает . Soah, а зачем мне сравнивать строки, по тому коду , что я привел выше, поидее должно в переменную темп выделяться памяти , как раз сколько сколько надо . Кстати потом дописал только что , пишу ещё temp = NULL; , но всё равно не помогает , да и если я буду делать такую проверку, каким мне ещё способом перемещать по тому адресу содержимое p[i] , если не так как я сделал? |
| Автор: Soah 4.7.2009, 22:46 |
а что же Вы сравниваете? |
| Автор: djezul 4.7.2009, 22:58 | ||||
| Soah, а всё врубился , спасибо , а то просто дебагер показывал вылет 3 строками ниже ))) Неа , не помогло , все равно вылет в этой строке показует
Добавлено через 4 минуты и 46 секунд Вот изменил код немного
|
| Автор: Soah 4.7.2009, 23:18 |
Если i = N-1, сколько будет i+1? Правельно i+1 = N, p[N] - выход за пределы массива и что делает эта строчка? |
| Автор: djezul 5.7.2009, 00:35 | ||
Soah,
Немного не понял, это к какому месту кода? В сортировки такого нет( |
| Автор: Soah 5.7.2009, 00:37 | ||
djezul, я уже устал цитировать этот код
|
| Автор: djezul 5.7.2009, 01:07 | ||||
Soah,
А что в нём не так ? Я исправил N на N + 1 , но ошибка не там возникает , даже при написании N + 1 , ошибка вылетает тут
|
| Автор: Soah 5.7.2009, 01:15 |
а почему так мало, давайте тогда уж N + 100 for (int i = 0 ; i < N ; i++ ) допустим N = 4 i = 0 i+1 = 1 -> p[0] и p[1] i = 1 i+1 = 2 -> p[1] и p[2] i = 2 i+1 = 3 -> p[2] и p[3] i = 3 i+1 = 4 -> p[3] и p[4] p[0]..p[4] -> 5 элементов, но ведь N = 4 |
| Автор: djezul 5.7.2009, 01:41 | ||||
Не понял смысла этой фразы. У меня так уже
У тогда все ваши расчёты будут верны.
и N будет равно 5. |
| Автор: Soah 5.7.2009, 01:56 |
можете обьяснить почему N+1? но ведь изначально количество элементов 4. да? N = 4 i < N +1 или i < 5 i = 0 i+1 = 1 -> p[0] и p[1] i = 1 i+1 = 2 -> p[1] и p[2] i = 2 i+1 = 3 -> p[2] и p[3] i = 3 i+1 = 4 -> p[3] и p[4] i = 4 i+1 = 5 -> p[4] и p[5] p[0]..p[5] -> 6 элементов, но ведь N = 4 смотрите, допустим у нас массив из 3 элементов, тогда первый элемент сравниваем со вторым, второй с третьим -> два сравнения - две итерации массив из 4 элементов, тогда первый элемент сравниваем со вторым, второй с третьим, третий с четвёртым -> три сравнения - три итерации |
| Автор: djezul 5.7.2009, 02:08 | ||
Вы хотите сказать , что N нужно присваивать N - 1 , то есть так
Попробовал , та же ошибка в том же месте) |
| Автор: Soah 5.7.2009, 02:13 | ||
но Вы хотя бы понимаете почему? а я уже спрашивал
|
| Автор: djezul 5.7.2009, 02:18 |
Да , спасибо , что так долго и упорно вдалбливали мне в голову , а не просто сказали что исправить)) А насчёт NULL , так препод сказал делать , правда в другой задаче, приводит к типу void * , а тут я впихнул , уже будучи в растеряности )))) Ещё раз спасибо) |
| Автор: djezul 5.7.2009, 02:35 | ||
Ну а здесь почему ошибка? |
| Автор: Soah 5.7.2009, 21:50 | ||||
указатели тут ни причём, надо правильно составлять алгоритмы и пользоваться отладчиком. |
| Автор: djezul 6.7.2009, 08:49 | ||||
А как насчёт этой строки немного выше
|
| Автор: Soah 6.7.2009, 12:10 | ||||||||
не заметил
djezul, |
| Автор: djezul 6.7.2009, 13:00 | ||||
Soah, я уже заменил код на такой
Насчёт правильного составления, тут и опыт играет роль, согласитесь . А отладчиком я пользуюсь , и пошаговой отладкой, уже раз 20 прошёл. Я не понимаю , почему q равно N поидее а не N - 1 . Причём такой момент , если я удаляю последний элемент, всё удаляется, а если не последний , то ошибка в этой строке , p[i] = new char[strlen(q[i]) + 1]; Вот именно , почему возникает вопрос? Ведб в 1 цикле, должно пропускаться . При этом если я делаю так
То ошибка возникает тут - for ( int i = 0 ; i < N ; i++ ) delete[] q[i]; |
| Автор: Soah 6.7.2009, 13:23 | ||||||||||
если пока в уме решать такие задачи не получается, возьмите ручку и решайте на бумажке допустим p[0] -> "123" p[1] -> "456" p[2] -> "789" p[3] -> "000" value = 1
после этого кода q[0] -> "123" q[1] -> ??? q[2] -> "789" как Вы думаете это правильно? вроде бы алгоритм правильный, сейчас времени проверить нет, только Вы делаете лишнюю работу
зачем создавать копию массива q, если можно присвоить p указатель на ту память которая уже есть
|
| Автор: djezul 6.7.2009, 13:32 | ||
Да, но если я удалю q , то и p , больше не будет , правильно? А мне нужно , чтобы p остался, правда без удалённого элемента) |
| Автор: Soah 6.7.2009, 13:45 |
а зачем удалять q? смотрите, p ->(указывает) на массив p[0]..p[3] p[0] -> "123" p[1] -> "456" p[2] -> "789" p[3] -> "000" value = 1 формируем q q[0] -> "123" q[1] -> "789" q[2] -> "000" удаляем память под строки p[0]..p[4] и массив p p = q, означает что p будет указывать туда где и q, то есть на массив строк("123", "789", "000") |
| Автор: djezul 6.7.2009, 13:51 |
Но ведь при 2 вызове функции , разве q сформируется правильно , если не отчистить занимаемою им память? Ведь возможно у меня будет p[0] -> "123" p[1] -> "456" p[2] -> "789" p[3] -> "000" Я удалю , останется q[0] -> "123" q[1] -> "789" q[2] -> "000" Я захочу добавить ещё 2 q[0] -> "123" q[1] -> "789" q[2] -> "000" q[3] -> "541" q[4] -> "000" И снова захочу удалить 5 элемент , но ведб в таком случае , функция правильно не отработает ? Или я что то не так понимаю? |
| Автор: Soah 6.7.2009, 13:57 | ||
мы ведь перебираем все элементы(N), а не все кроме последнего(N-1) |
| Автор: djezul 6.7.2009, 14:39 | ||
эх.... точно, ведь исправлял эту ошибку, но тогда была ошибка в 1 цикле. Но когда не помогло наверное сделал откат , и эта ошибка снова осталась. Спасибо за помощь. |
| Автор: ller 14.7.2009, 21:32 | ||||
| Вопрос по теме. Не буду новую заводить. Есть некоторый класс
Я понимаю, что так делать нельзя, но есть какие то пути как сделать указание элемента в виде масива n-мерного. Один из вариантов как я вижу, это использовать
Но хочется сделать велосипед, в качестве получения опыта |