Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Проблема с new/delete

5.2K
10 февраля 2004 года
Dilon
19 / / 04.01.2004
Вот пример кода, отладчиком посмотрел, при вызове delete str - acces violation
Цитата:

int count=1,len=0;
char *str,temp[5];
char s[]="aaaaaaaaaassssssssssyyyyyyyyyyyyyyuiuuuuuddddddddd";
len=strlen(s);

str=new char;
str=(char*)0;


for (int i=1;i<len;i++) {
while(s==s[i-1]) {
count++;
i++;
}
sprintf(temp,"%c%c%d%c",s[i-1],'(',count,')');
strcat(str,temp);
count=1;
}
printf("Compressed string: %s",str);
delete str;


Как быть?

319
10 февраля 2004 года
xelos
577 / / 27.02.2003
Цитата:
Originally posted by Dilon
Вот пример кода, отладчиком посмотрел, при вызове delete str - acces violation

Как быть?


а если перед делете занулить указатель?типа
str=NULL;
и в начале когда нуль присваиваешь, если ты кго хочешь обнулить, имхо лучше использовать такое же выражение.

2.6K
10 февраля 2004 года
Hearse
89 / / 19.01.2004
Цитата:
Originally posted by xelos
а если перед делете занулить указатель?типа
str=NULL;
и в начале когда нуль присваиваешь, если ты кго хочешь обнулить, имхо лучше использовать такое же выражение.



Лирическое отступление - действительно, указателям лучше присваивать NULL, нежели (type*)0, так как стандарт языка C++ не гарантирует, что внутреннее значение NULL==0.
Удаление указателя со значением NULL по стандарту вроде бы не страшно, но в данном конкретном случае ведет к memory leak.

Проблема в строчках

 
Код:
str=new char;
str=(char*)0;

После выполнения первой строки указатель str указывает на начало выделенного блока памяти, после выполнения второй адрес выделенного блока теряется, в результате чего при попытке высвободить пямять появляется acсess violation. Решение - убрать вторую строку.

Далее, судя по коду
 
Код:
strcat(str,temp);

str должен быть указателем на массив символов, что в действительности не так, такой код тоже можеть вызвать acсess violation. Решение
 
Код:
str=new char[SIZE];

Где SIZE необходимая длина строки.

И еще - такие штуки я бы не советовал бы использовать
 
Код:
for (int i=1;i<len;i++) {
while(s==s[i-1]) {
count++;
i++;
}
5.2K
11 февраля 2004 года
Dilon
19 / / 04.01.2004
Убрать обнуление, конечно можно, но в указателе появляется всякий "мусор" и при выводе на экран строка не выглядит слишком читабельно в начале :)
 
Код:
str=new char[SIZE];

было бы оптимальным вариантом, но я не знаю этот SIZE, т.е. начальная строка может быть любой, соответсвенно и размер новой неизвестен...
2.6K
11 февраля 2004 года
Hearse
89 / / 19.01.2004
Строка нужной длины
 
Код:
str=new [strlen(s)+1];


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

 
Код:
str[0]=0;
или
*str=0;


Но ни в коем случае как это делал ты.
3
11 февраля 2004 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by Dilon
Вот пример кода, отладчиком посмотрел, при вызове delete str - acces violation

Как быть?



Если уж ты пишешь на С++, то почему бы не использовать std::string ?

5.2K
11 февраля 2004 года
Dilon
19 / / 04.01.2004
Цитата:
Originally posted by Green


Если уж ты пишешь на С++, то почему бы не использовать std::string ?



Так то оно так, stl - удобный инструмент, но если вам придется писать под какой-нидь Micro C, который даже не слышал про stl?

3
11 февраля 2004 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by Dilon

Так то оно так, stl - удобный инструмент, но если вам придется писать под какой-нидь Micro C, который даже не слышал про stl?



В каком-нибудь Micro C не будет и new/delete :D

1.8K
11 февраля 2004 года
MishaSt
170 / / 11.08.2003
Цитата:
Originally posted by Green


В каком-нибудь Micro C не будет и new/delete :D


Классический С это:
malloc - выделение памяти
free - освобождение её
memset - заполнение памяти значением
memcpy - копирование участков памяти
А вот что такое Micro C незнаю, может там их и нет. Хотя в Watcom C,Borland C, Microsoft C есть эти функции.

5.2K
11 февраля 2004 года
Dilon
19 / / 04.01.2004
Цитата:
Originally posted by Green


В каком-нибудь Micro C не будет и new/delete :D


Зато будет malloc/free. Заменить вызовы new/delete проще, чем переписать весь код с stl на чистый си:D

3
11 февраля 2004 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by Dilon

Зато будет malloc/free. Заменить вызовы new/delete проще, чем переписать весь код с stl на чистый си:D



Ну для начала скажу, что переписать STL на С невозможно.
И еще добавлю, что new - это не аналог malloc, соотв-но, delete не аналог free.

Далее, укажи все же начем пишешь?
В любом случае твой код сплошь в ОПАСНЫХ ошибках:
1) memory leak

 
Код:
str=new char;
  str=(char*)0;

2) buffer overflow
 
Код:
char temp[5];
  .............
  sprintf(temp,"%c%c%d%c",s[i-1],'(',count,')');

кстати, зачем так сложно с sprintf, можно ведь так:
sprintf(temp,"%c(%d)",s[i-1],count);
3) buffer overflow!!!
 
Код:
str=new char;
  .............
  strcat(str,temp);

А если учесть ещё, что str=0 !
5.2K
11 февраля 2004 года
Dilon
19 / / 04.01.2004
Цитата:
Originally posted by Green

Ну для начала скажу, что переписать STL на С невозможно.



Вообще если повнимательней приглядеться к моему посту можно заметить что я не в коем случае не предлагал переписывать саму стл, а код, написанный с помощью нее;)

Цитата:
И еще добавлю, что new - это не аналог malloc, соотв-но, delete не аналог free


Понятно, что не аналог, однако и те и другие работают с динамической памятью, следовательно в некоторых случаях (а особенно в урезанных компиляторах) можно обойтись и обычными malloc/free. Когда же с стл вы так не никогда извернетесь :D

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог