Dr.Yevhenius
|
|
« : 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
|
|
« Ответ #1 : 24-11-2009 16:17 » |
|
Inkognito, а проверить?
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
Dr.Yevhenius
|
|
« Ответ #2 : 24-11-2009 16:30 » |
|
Sla, зачем мне твой ответ, если ответа как такового нету. Чтоб проверить, нужно забить память до отказа, выводить адрес предыдущего значения, а в конце показать последний адрес снова (для сравнения). Но это всё лишняя головная боль и время. Почему бы не спросить у тех, кно наверняка знает? А если этот форум не для вопросов, укажите это на главной странице, и меньше человек перестанут здесь неполучать ответы.
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #3 : 24-11-2009 16:39 » |
|
Inkognito, разве в твоем выражении не указывается прямо, что temp = 0 - ошибка выделения?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Dr.Yevhenius
|
|
« Ответ #4 : 24-11-2009 16:47 » |
|
Понял, как протупил с if в строке 3. RXL, спасибо.
|
|
|
Записан
|
|
|
|
Михалыч
|
|
« Ответ #5 : 24-11-2009 17:04 » |
|
|
|
« Последнее редактирование: 24-11-2009 17:06 от Михалыч »
|
Записан
|
Поживем - увидим... Доживем - узнаем... Выживу - учту
|
|
|
Вад
|
|
« Ответ #6 : 24-11-2009 18:15 » |
|
Дополню: если в случае с int зависит от настроек, то в случае со сложными типами также может быть переопределён оператор new, и поведение, разумеется, будет всецело зависеть от новой реализации.
|
|
|
Записан
|
|
|
|
Sla
|
|
« Ответ #7 : 25-11-2009 06:49 » |
|
Inkognito, объясняю про проверку. Но сначала вопрос. Сколько выделяется памяти под одни указатель int? А под два int? А под массив int?
Если ответишь себе, то и поймешь про проверку.
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
RXL
|
|
« Ответ #8 : 25-11-2009 07:04 » |
|
Только заметил казус в строке 2... Ужос!
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
sss
Специалист
Offline
|
|
« Ответ #9 : 26-11-2009 01:28 » |
|
RXL, никакой не ужас - копирующий конструктор.
|
|
|
Записан
|
while (8==8)
|
|
|
RXL
|
|
« Ответ #10 : 26-11-2009 04:18 » |
|
sss, тогда — синтаксический ужос!
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
sss
Специалист
Offline
|
|
« Ответ #11 : 26-11-2009 07:23 » |
|
согласен!
|
|
|
Записан
|
while (8==8)
|
|
|
Dr.Yevhenius
|
|
« Ответ #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
Молодой специалист
Offline
|
|
« Ответ #13 : 13-01-2010 12:30 » |
|
Так делать нельзя как минимум по 2 причинам: 1. массив выделялся статически (это даже не массив а константная строка, т.е. это не char *, а const char *), поэтому delete его удалять нельзя 2. даже если бы память под массив была выделена динамически, удалять можно только имея ссылку на первй элемент, а не на какой-то там посередине (при этом удаляться будет весь массив, а не его часть, отдельно часть удалить нельзя).
Кстати читать память никто не запрещает, так что обращаться к "несуществующим" элементам массива (если они лежат в "разрешенной" области памяти процесса) только для чтения можно (но как правило не нужно), просто там мусор (или чужие данные)
|
|
« Последнее редактирование: 13-01-2010 12:35 от lapulya »
|
Записан
|
С уважением Lapulya
|
|
|
Dr.Yevhenius
|
|
« Ответ #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 »
|
Записан
|
|
|
|
Вад
|
|
« Ответ #15 : 13-01-2010 12:56 » |
|
Теоретически "освобождать правую часть" можно realloc - со всеми вытекающими ограничениями. Только зачем? И зачем в вышеприведённом примере массив, принадлежащий объекту st, нужно снаружи резать? Оно так не сломается?
|
|
|
Записан
|
|
|
|
Dr.Yevhenius
|
|
« Ответ #16 : 13-01-2010 13:00 » |
|
Я немножко не выспался... Первую строку последнего примера поменял. ...нужно снаружи резать? Оно так не сломается?
Задание гипотетическое. cstr возвращает нормальный указатель, который удалить можно без всяких проблем. А то надоело уже - что не напишу, всё выбивает и выбивает (при удалении). P.S. st - обьект класса astring.
|
|
« Последнее редактирование: 13-01-2010 13:05 от Inkognito »
|
Записан
|
|
|
|
darkelf
Молодой специалист
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
|
|
« Ответ #18 : 13-01-2010 13:15 » |
|
Создать указатель, с помощью которого можно будет управлять (и даже удалать из кучи) какой-то частью даных существующего в динамической памяти массива.
|
|
« Последнее редактирование: 13-01-2010 13:25 от Inkognito »
|
Записан
|
|
|
|
darkelf
Молодой специалист
Offline
|
|
« Ответ #19 : 13-01-2010 13:17 » |
|
указатель не контролирует и управляет, а указывает. это обычная ячейка памяти, которая содержит адрес объекта, не больше - не меньше. Если Вам нужно обращаться к какой-то части массива, но при этом не изменять основной, то как уже было сказано - делается копия необходимой части.
|
|
« Последнее редактирование: 13-01-2010 13:21 от darkelf »
|
Записан
|
|
|
|
Dr.Yevhenius
|
|
« Ответ #20 : 13-01-2010 13:24 » |
|
*** то что было до изменения ***
Текст поста поменял. Вам нужно обращаться к какой-то части массива, но при этом не изменять основной
С чего Вы взяли? Как раз нужно менять существующий, а не создавать копию. Тему буду считьть закрытой. ...А то еще побьют меня здесь (шутка).
|
|
« Последнее редактирование: 13-01-2010 13:30 от Inkognito »
|
Записан
|
|
|
|
darkelf
Молодой специалист
Offline
|
|
« Ответ #21 : 13-01-2010 13:31 » |
|
память под массив выделяется целиком, по-этому удалять можно ТОЛЬКО с конца (функцией realloc()), и для этого Вам будет необходим адрес начала массива, а не указатель куда-то в средину. В общем то, что Вы хотите сделать, можно сделать через vector, но это уже будут не массивы, и не совсем указатели.
|
|
« Последнее редактирование: 13-01-2010 16:18 от darkelf »
|
Записан
|
|
|
|
Антон (LogRus)
|
|
« Ответ #22 : 14-01-2010 06:38 » |
|
.............. Задание гипотетическое. cstr возвращает нормальный указатель, который удалить можно без всяких проблем. ..............
string управляет памятью в которой хранится результат c_str и удалять эту память ни в коем случае нельзя. удалять массив с середины тем более выделенный через new недопустимо посмотри на free и delete, ты видишь передачу размера? я нет.
|
|
|
Записан
|
Странно всё это....
|
|
|
Dr.Yevhenius
|
|
« Ответ #23 : 14-01-2010 06:55 » |
|
string управляет памятью в которой хранится результат c_str и удалять эту память ни в коем случае нельзя.
Только не string, а astring, и не c_str(), а cstr().
|
|
|
Записан
|
|
|
|
|