Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Указатели  (Прочитано 23450 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« : 24-11-2009 16:09 » 

Код:
0: bool foo()
1: {
2: int * temp = new int(0);
3: if(!(temp = new int(1)))
4: // Не хватило памяти
5: return false;
6: }
Подскажите пожалуйста, после того, как в строке 3 не хватит памяти на виделение нового числа, указатель temp будет указывать на значение 0, или на какую-то другую область памяти?
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 24-11-2009 16:17 » 

Inkognito,  а проверить?
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« Ответ #2 : 24-11-2009 16:30 » 

Sla, зачем мне твой ответ, если ответа как такового нету. Чтоб проверить, нужно забить память до отказа, выводить адрес предыдущего значения, а в конце показать последний адрес снова (для сравнения). Но это всё лишняя головная боль и время. Почему бы не спросить у тех, кно наверняка знает? А если этот форум не для вопросов, укажите это на главной странице, и меньше человек перестанут здесь неполучать ответы.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 24-11-2009 16:39 » 

Inkognito, разве в твоем выражении не указывается прямо, что temp = 0 - ошибка выделения?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« Ответ #4 : 24-11-2009 16:47 » 

Понял, как протупил с if в строке 3. RXL, спасибо.
Записан
Михалыч
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 24-11-2009 17:04 » 

Есть 2 варианта, либо NULL-указатель, либо будет бросать исключение... Все зависит от того, что за компилятор, ну и от
того, как его использовать...
Например см. тут - почти такой же вопрос Улыбаюсь
http://gcc.gnu.org/ml/gcc-help/2007-09/msg00130.html
ну и дополнительно сюда Улыбаюсь
http://msdn.microsoft.com/en-us/library/kftdy56f(VS.71).aspx
http://www.serc.iisc.ernet.in/ComputingFacilities/systems/cluster/vac-7.0/html/language/ref/clrc05snewhnd.htm#HDRSNEWHND
http://www.glenmccl.com/bett_003.htm

Так что, видимо, не все так просто Улыбаюсь
« Последнее редактирование: 24-11-2009 17:06 от Михалыч » Записан

Поживем - увидим... Доживем - узнаем... Выживу - учту  Улыбаюсь
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 24-11-2009 18:15 » 

Дополню: если в случае с int зависит от настроек, то в случае со сложными типами также может быть переопределён оператор new, и поведение, разумеется, будет всецело зависеть от новой реализации.
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 25-11-2009 06:49 » 

Inkognito, объясняю про проверку.
Но сначала вопрос.
Сколько выделяется памяти под одни указатель int?
А под два int?
А под массив int?

Если ответишь себе, то и поймешь про проверку.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #8 : 25-11-2009 07:04 » 

Только заметил казус в строке 2... Ужос!
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
sss
Специалист

ru
Offline Offline

« Ответ #9 : 26-11-2009 01:28 » 

RXL, никакой не ужас - копирующий конструктор.
Записан

while (8==8)
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 26-11-2009 04:18 » 

sss, тогда — синтаксический ужос!
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
sss
Специалист

ru
Offline Offline

« Ответ #11 : 26-11-2009 07:23 » 

согласен!
Записан

while (8==8)
Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« Ответ #12 : 13-01-2010 12:02 » 

У меня еще вот вопрос...
Код:
Код:
	char * array = "1234567890";
char * righthalf = array + 5;

cout << array[0] << array[5] << righthalf[0]; // Демонстрируем, что array[5] и righthalf[0] - одинаковые
delete [] righthalf; // Типа...
cout << array[4] << array[5]; // Попытка вывести 4й (существующий) и 5й (несуществующий) елементы
Чего хотел от кода: удалить не весь массив (array), а только его правую половину (righthalf). Есть какой-то метод (не функция, а алгоритм), чтоб "прибиндить" к указателю часть другого массива? В даном случае, к righthalf'у правую половину array'я. Для программы не нужно, но всё-равно интересно...  Улыбаюсь
« Последнее редактирование: 13-01-2010 12:04 от Inkognito » Записан
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #13 : 13-01-2010 12:30 » 

Так делать нельзя как минимум по 2 причинам:
1. массив выделялся статически (это даже не массив а константная строка, т.е. это не char *, а const char *), поэтому delete его удалять нельзя
2. даже если бы память под массив была выделена динамически, удалять можно только имея ссылку на первй элемент, а не на какой-то там посередине (при этом удаляться будет весь массив, а не его часть, отдельно часть удалить нельзя).  

Кстати читать память никто не запрещает, так что обращаться к "несуществующим" элементам массива (если они лежат в "разрешенной" области памяти процесса) только для чтения можно (но как правило не нужно), просто там мусор (или чужие данные)
« Последнее редактирование: 13-01-2010 12:35 от lapulya » Записан

С уважением Lapulya
Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« Ответ #14 : 13-01-2010 12:45 » 

1. массив выделялся статически (это даже не массив а константная строка, т.е. это не char *, а const char *), поэтому delete его удалять нельзя
М-да, код я привел плохой, согласен. Вот иной:
Код:
	char * array = 0;
array = st.cstr();
array[2] = '-';
cout << array;
delete [] array;
array = 0;

2. даже если бы память под массив была выделена динамически, удалять можно только имея ссылку на первй элемент, а не на какой-то там посередине (при этом удаляться будет весь массив, а не его часть, отдельно часть удалить нельзя).
Речь не об удалении массива через N-ый элемент.

Кстати читать память никто не запрещает, так что обращаться к "несуществующим" элементам массива (если они лежат в "разрешенной" области памяти процесса) только для чтения можно (но как правило не нужно), просто там мусор (или чужие данные)
В лучшем случае - мусор.


Цель: создать полноценный указатель, которий будет подмассивом существующего и который можно нормально удалять. И всё-равно в даный момент, как на это массив-оригинал отреагирует.
« Последнее редактирование: 13-01-2010 12:58 от Inkognito » Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 13-01-2010 12:56 » 

Теоретически "освобождать правую часть" можно realloc - со всеми вытекающими ограничениями. Только зачем? Улыбаюсь
И зачем в вышеприведённом примере массив, принадлежащий объекту st, нужно снаружи резать?  Оно так не сломается?
Записан
Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« Ответ #16 : 13-01-2010 13:00 » 

Я немножко не выспался... Первую строку последнего примера поменял.

...нужно снаружи резать?  Оно так не сломается?
Задание гипотетическое. cstr возвращает нормальный указатель, который удалить можно без всяких проблем. А то надоело уже - что не напишу, всё выбивает и выбивает (при удалении). Улыбаюсь

P.S. st - обьект класса astring.
« Последнее редактирование: 13-01-2010 13:05 от Inkognito » Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #17 : 13-01-2010 13:08 » 

сорри, но всё-же подмассив, это подмассив (хотя насколько я помню, в языках C/C++, таких вещей нет), а указатель, это указатель. Если Вам нужно, то можете необходимую часть массива скопировать в выделенный другой массив, который впоследствии удалить. Пример:
Код:
char* a = "lalalajujuju";
char* b;

if ((b = (char*)malloc(5)) != NULL)
{ memcpy(b, a + 5, 4);
  b[4] = 0;

  b[0] = a[7];

  free(b);
}
« Последнее редактирование: 13-01-2010 13:10 от darkelf » Записан
Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« Ответ #18 : 13-01-2010 13:15 » 

Создать указатель, с помощью которого можно будет управлять (и даже удалать из кучи) какой-то частью даных существующего в динамической памяти массива.
« Последнее редактирование: 13-01-2010 13:25 от Inkognito » Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #19 : 13-01-2010 13:17 » 

указатель не контролирует и управляет, а указывает. это обычная ячейка памяти, которая содержит адрес объекта, не больше - не меньше. Если Вам нужно обращаться к какой-то части массива, но при этом не изменять основной, то как уже было сказано - делается копия необходимой части.
« Последнее редактирование: 13-01-2010 13:21 от darkelf » Записан
Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« Ответ #20 : 13-01-2010 13:24 » 

*** то что было до изменения ***
Текст поста поменял.

Вам нужно обращаться к какой-то части массива, но при этом не изменять основной
С чего Вы взяли? Как раз нужно менять существующий, а не создавать копию.

Тему буду считьть закрытой.
...А то еще побьют меня здесь (шутка).
« Последнее редактирование: 13-01-2010 13:30 от Inkognito » Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #21 : 13-01-2010 13:31 » 

память под массив выделяется целиком, по-этому удалять можно ТОЛЬКО с конца (функцией realloc()), и для этого Вам будет необходим адрес начала массива, а не указатель куда-то в средину. В общем то, что Вы хотите сделать, можно сделать через vector, но это уже будут не массивы, и не совсем указатели.
« Последнее редактирование: 13-01-2010 16:18 от darkelf » Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #22 : 14-01-2010 06:38 » 

..............
Задание гипотетическое. cstr возвращает нормальный указатель, который удалить можно без всяких проблем.
..............
string управляет памятью в которой хранится результат c_str и удалять эту память ни в коем случае нельзя.

удалять массив с середины тем более выделенный через new недопустимо
посмотри на free и delete, ты видишь передачу размера? я нет.
Записан

Странно всё это....
Dr.Yevhenius
Опытный

ua
Offline Offline
Пол: Мужской

« Ответ #23 : 14-01-2010 06:55 » new

string управляет памятью в которой хранится результат c_str и удалять эту память ни в коем случае нельзя.
Только не string, а astring, и не c_str(), а cstr().
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines