С++: простейший вопрос по указателям

0000


int *p = new int(999);
Log (L"1 %i\n", *p);
delete p;
Log (L"2 %i\n", *p);

Выведет на экран два раза 999 Это так и должно быть? Как память то освободить?
P.S. Читаю книгу.

ppplva

Это совпадение.

0000


А что на самом то дле должно быть?
Задача чуть посложнее (я понял, что у меня и с простой проблемы)

//имеется массив указателей на объекты
CObject* Objects [OBJECT_MAX]
//Допустим добавили туда объект
Objects[1] = new CObject ;
// А потом удалили
delete Objects[1];
// А теперь проверяю, что он удалился
printf (...Objects[1]->ПолучениеСвойства..);
// Нифига! Объект есть.

P.S. Создать сообщение раньше надавилось.

slonishka

у меня удаляется...

Vladislav177Rus

ssh:~$ cat 1.cpp
#include <iostream>

using namespace std;

int main{
int *p = new int(999);
cout << *p << endl;
delete p;
cout << *p << endl;
return 0;
}
ssh:~$ g++ 1.cpp
ssh:~$ ./a.out
999
0

kokoc88

Как память то освободить?
Ты её освободил. В Си++ можно использовать любой указатель на память, язык не проверяет его валидность. Утечки памяти отлавливаются специальными утилитами, коих море под любую платформу.

Vladislav177Rus

ssh:~$ valgrind a.out
==30461== Memcheck, a memory error detector for x86-linux.
==30461== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al.
==30461== Using valgrind-2.4.0, a program supervision framework for x86-linux.
==30461== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al.
==30461== For more details, rerun with: -v
==30461==
999
==30461== Invalid read of size 4
==30461== at 0x80487AC: main (in /home/sharp/a.out)
==30461== Address 0x1BB37028 is 0 bytes inside a block of size 4 free'd
==30461== at 0x1B904CA8: operator delete(void*) (vg_replace_malloc.c:155)
==30461== by 0x80487A8: main (in /home/sharp/a.out)
999
==30461==
==30461== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 19 from 1)
==30461== malloc/free: in use at exit: 0 bytes in 0 blocks.
==30461== malloc/free: 1 allocs, 1 frees, 4 bytes allocated.
==30461== For counts of detected errors, rerun with: -v
==30461== No malloc'd blocks -- no leaks are possible.

Он кивнул своей головой в знак согласия, подтверждая сказанное.

0000

Блин, наверно это какая то очередная тонкость проганья под WinCE (проверил не только в эмуляторе). Собрал проект под Win32 действительно все освободилось.
Может это как то свзяано с реализацией работы с памятью на КПК?

istran

говорят же тебе, что память освободилась. Т.е. если приложению понадобиться память,
то этот блок может быть использован. Если для тебя критично, чтобы информация удалялась
сразу же после освобожденя, то можешь например забивать её нулями(или, для параноиков, рандомными числами перед освобождением.

amkharchenko

[off] А где можно на твою фотку посмотреть? Чисто для общего развития.

0000

2
> говорят же тебе, что память освободилась
Собственно это и хотелось узнать, просто факт существования данных наводил на мысль что нифига (у других то все зачищалось).
2
Нигде нельзя - так и будешь необразованным
2blind
Все равно в С++ прогеры не пойду.

pav7

у тебя тут по стандарту undefined behaviour
какое тебе дело до того, каков будет результат, если он непредсказуем?

0000

Да мне пофиг, просто мне казалось, что там NULL должен быть или вообще падать должно.
Вообщем вопрос закрыт, сам NULL-ом забиваю.

ppplva

*p = NULL ?
Перед удалением или после ?

0000

Конечно перед!

pav7

не надо нуллом забивать
просто не надо юзать больше этот указатель

0000

> просто не надо юзать больше этот указатель
Хм, мне под мою задачку надо - может я просто криво реаилизовываю:
Имеется массив указателей на объекты, инициализируемый {}
В этот массив могут добавляться и удаляться элементы.
Я делаю так - при вставке ищу первый NULL указатель и присваиваю ему указатель на объект.
При удалении: по номеру, выполняю деструктор для объекта, на который указывает указатель, а указателю присваиваю NULL.
Это эквивалентно или нет?

CObject Objects [15] = {};
Objects [10] = new CObject ;
...
delete Objects[10]
и
Objects[10]->~CObject;

slonishka

> *p = NULL
это присваивание не указателю, а тому, на что он указывает.
указатель после delete p; и так должен быть нулём.
вроде так.

pav7

деструктор вызовет delete, не надо его самому вызывать
и зачем тебе сишный массив? юзай список из стл-я, зачем лишний гемор себе наживать?

0000

Список не катит Нужен вызов объектов по (int) id и чем быстрее доступ тем лучше (потому в сторону stl словарей копать не стал).

0000

Гы, похоже что так

slonishka

Список не катит
а вектор — медленно?

Oper

Objects[10]->~CObject;

kokoc88

Objects[10]->~CObject;
Вообще говоря, не жесть. Если использовать правильно. Такой вызов можно использовать для работы с мемори пулами.

0000

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

kokoc88

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

0000

Я подозревал вчера даже Аммерааля почитал. Мне важна скорость доступа, на время добавления и удаления элементов пофиг. Не думаю что обычный массив тут словарь зарулит.

slonishka

Не думаю что обычный массив тут словарь зарулит.
в map скорость доступа по индексу = O(log(n. для большой таблицы это вроде как более-менее.
кроме того, можно использовать hash_map (17.6 в Страуструпе).
или: http://www.sgi.com/tech/stl/HashedAssociativeContainer.html

Oper

Жесть относилась скорее ко всему коду автара, просто неудачно цытату оформил
А вообще автору - прежде чем использовать vector - почитай хотя бы про C книжки, так как хорошего понимания, как происходит работа с памятью у тебя похоже нет.

Codcod

Плакал...
попробуй записать по этому роинтеру ...
А вообще: из списка она уже удалилась, а куда значение указателя систему не волнует, чисто твои проблемы.

0000

> почитай хотя бы про C книжки
Вот еще
А по С++ читаю периодически понемногу Липмана и Аммералля.
Поскольку мало занимаюсь проганьем, то получается очень немного.
Оставить комментарий
Имя или ник:
Комментарий: