Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Изменение указателя на массив указателей 
V
    Опции темы
nibble
  Дата 14.3.2009, 14:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 14.3.2009
Где: Москва

Репутация: нет
Всего: нет



Код

char *words[3] = {"Apple", "Mother", "New York"};

char **newWords = new char*[4];
    
newWords[0] = words[0];
newWords[1] = words[1];
newWords[2] = words[2];
newWords[3] = "Forever";

words = newWords;           // error: incompatible types in assignment of 'char**' to 'char* [3]'

std::cout << words[0] << ", " << words[1] << ", " << words[2] << ", " << words[3] << std::endl;


words - массив указателей на строки, я правильно выражаюсь? Точнее даже указатель на такой массив, да?
И newWords - тоже точно такой же указатель на массив указателей...

Я пишу "words = newWords;". Мне нужно, чтобы указатель words ссылался не на начальный массив, а на новый, где слов стало 4, а не 3.
В чем ошибка?..

Это сообщение отредактировал(а) nibble - 14.3.2009, 14:52
PM MAIL ICQ   Вверх
Rififi
Дата 14.3.2009, 15:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1254
Регистрация: 9.3.2008

Репутация: 3
Всего: 36



nibble
words - массив указателей на строки, я правильно выражаюсь? Точнее даже указатель на такой массив, да?
нет.
word - это массив константных указателей на char.

а вот newWords - это действительно указатель.
ты думаешь что это одно и тоже, и пытаешься убедить в этом компилятор - отсюда и ошибка.
PM MAIL   Вверх
mes
Дата 14.3.2009, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(nibble @  14.3.2009,  13:51 Найти цитируемый пост)
Мне нужно, чтобы указатель words ссылался не на начальный массив, а на новый, где слов стало 4, а не 3.

не получится, так как первоначальный массив статический и изменению размера не подлежит. (Неправилен сам замысел, не говоря о путанице массивов и указателей)

Это сообщение отредактировал(а) mes - 14.3.2009, 15:09


--------------------
PM MAIL WWW   Вверх
nibble
Дата 14.3.2009, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 14.3.2009
Где: Москва

Репутация: нет
Всего: нет



Код

char **words;

char **OldWords = new char*[2];
OldWords[0] = "Sister";
OldWords[1] = "Brother";
words = OldWords;

char **NewWords = new char*[3];
NewWords[0] = words[0];
NewWords[1] = words[1];
NewWords[2] = "Mother";
words = NewWords;

std::cout << words[0] << ", " << words[1] << ", " << words[2] << ", " << words[3] << std::endl;

Теперь верно? Я создаю указатель words. Сначала он указывал на массив указателей на две строки, потом на три.

Добавлено @ 15:52
Код

char **words;

char **OldWords = new char*[2];
OldWords[0] = "Sister";
OldWords[1] = "Brother";
words = OldWords;

char **NewWords = new char*[3];
NewWords[0] = words[0];
NewWords[1] = words[1];
NewWords[2] = "Mother";

delete words;
words = NewWords;
delete NewWords;

std::cout << words[0] << ", " << words[1] << ", " << words[2] << ", " << words[3] << std::endl;


Строками "delete words;" и "delete NewWords;" дейсвительно удаляются старые массивы указателей? Память освобождается? Или он удаляет пустоту?
Ни как не разобраться в этих звёздочках...

Ведь когда я пишу "delete words;", должен удаляться массив OldWords, ведь words ссылается на него. А после "delete NewWords;" удалится массив NewWords? Выходит, всё удалится... почему тогда слова нормально выводятся на экран?.. 

Это сообщение отредактировал(а) nibble - 14.3.2009, 15:56
PM MAIL ICQ   Вверх
zim22
Дата 14.3.2009, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(nibble @  14.3.2009,  15:46 Найти цитируемый пост)
Теперь верно?

запусти и посмотри. работает - значит верно smile



--------------------
PM MAIL   Вверх
Rififi
Дата 14.3.2009, 15:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1254
Регистрация: 9.3.2008

Репутация: 3
Всего: 36



nibble
Строками "delete words;" и "delete NewWords;" дейсвительно удаляются старые массивы указателей? 
В этих строках происходит undefined behavior из за неправильной последовательности неправильных действий

правильная последовательность правильных действий
Код
delete [] words;
words = NewWords;
std::cout << words[0] << ", " << words[1] << ", " << words[2] << ", " << words[3] << std::endl;
delete [] NewWords;

PM MAIL   Вверх
nibble
Дата 14.3.2009, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 14.3.2009
Где: Москва

Репутация: нет
Всего: нет



Можно обойтись и без OldWords:
Код

    char **words;
    
    words = new char*[2];
    words[0] = "Sister";
    words[1] = "Brother";
    
    char **NewWords = new char*[3];
    NewWords[0] = words[0];
    NewWords[1] = words[1];
    NewWords[2] = "Mother";
    
    delete [] words;
    words = NewWords;
    delete [] NewWords;

    std::cout << words[0] << ", " << words[1] << ", " << words[2] << ", " << words[3] << std::endl;


Цитата
правильная последовательность правильных действий

Почему нелья "delete [] NewWords;" до вывода на экран?

В отладчике вообще не видно никакой реакции на "delete [] words;" и "delete [] NewWords;". Он не удаляет временный массив указателей NewWords. А мне нужно, чтобы удалял...
PM MAIL ICQ   Вверх
zim22
Дата 14.3.2009, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(nibble @  14.3.2009,  16:25 Найти цитируемый пост)
вообще не видно никакой реакции

а какую реакцию ты ждёшь увидеть?

Добавлено через 1 минуту и 3 секунды
Цитата(nibble @  14.3.2009,  16:25 Найти цитируемый пост)
Почему нелья "delete [] NewWords;" до вывода на экран?

потому что это:
Код

words = NewWords;



--------------------
PM MAIL   Вверх
nibble
Дата 14.3.2009, 16:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 14.3.2009
Где: Москва

Репутация: нет
Всего: нет



То есть реакции не должно быть? Он сотрёт ячейки памяти только когда они ему понадобятся?
И именно по этому всё выводится на экран, несмотря на "delete [] NewWords;" в неположенном месте?..

Выходит, words и NewWords становятся указателями на один и тот же объект. И "delete [] NewWords;" - это то же самое, что и "delete [] words;".
Я правильно понимаю?
PM MAIL ICQ   Вверх
mes
Дата 14.3.2009, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(nibble @  14.3.2009,  15:40 Найти цитируемый пост)

Выходит, words и NewWords становятся указателями на один и тот же объект. И "delete [] NewWords;" - это то же самое, что и "delete [] words;".
Я правильно понимаю? 

да, уничтожается не указатель, а тот массив/объект на который он указывает.


--------------------
PM MAIL WWW   Вверх
zim22
Дата 14.3.2009, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(nibble @  14.3.2009,  16:40 Найти цитируемый пост)
И именно по этому всё выводится на экран

у меня ничего не выводится на экран. как оно может выводиться, когда мы удалили указатели?

и кстати, words[3] нет такого элемента.

попробуй этот код. он тоже у тебя корректно работает?
Код
#include <iostream>

int main()
{
    char **words;
    
    words = new char*[2];
    words[0] = "Sister";
    words[1] = "Brother";
    
    char **NewWords = new char*[3];
    NewWords[0] = words[0];
    NewWords[1] = words[1];
    NewWords[2] = "Mother";
    
    delete [] words;
    words = 0;
    words = NewWords;
    delete [] NewWords;
    NewWords = 0;

    std::cout << words[0] << ", " << words[1] << ", " << words[2] << ", " << words[3] << std::endl;
    return 0;
}




--------------------
PM MAIL   Вверх
nibble
Дата 14.3.2009, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 14.3.2009
Где: Москва

Репутация: нет
Всего: нет



Работает. Точно также, как и мой.
Выводит "Sister, Brother, Mother, Current language:  auto; currently c++"
"Current language:  auto; currently c++" - это из-за отсутсвия words[3] он случайно попадает на эту строку, я так понимаю.

Как он может работать, если мы всё поудаляли?.. Если нет ни NewWords, ни words?..
PM MAIL ICQ   Вверх
mes
Дата 14.3.2009, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(nibble @  14.3.2009,  16:23 Найти цитируемый пост)
Как он может работать, если мы всё поудаляли?.. Если нет ни NewWords, ни words?.. 

Упрощено: Вы удалили объект, и oн освободил занимаемую память. содержимое памяти не изменилось и не изменится пока эта область не будет захвачена другим объектом smile


Это сообщение отредактировал(а) mes - 14.3.2009, 17:34


--------------------
PM MAIL WWW   Вверх
math64
Дата 15.3.2009, 11:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



1. В данном случае delete words; и delete[] words; - одно и то же, отличие было бы только если бы words был бы массивом объектов-классов с деструктором. В первом случае вызвался бы деструктор только для первого объекта, во втором - для всех.
2. char* words[] = { "Apple", "Mother", "New York"}; - массив указателей, где вы видите const?
*words[0] = 'U'; выполнить нельзя, но компилятор этого не заметит.  Во время выполнения в Linux будет ошибка записи в память, доступной только для чтения, в DOS выполнится нормально. 
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0891 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.