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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> нужно ли удалять указатель на символьный массив с 
:(
    Опции темы
polin11
Дата 8.8.2015, 00:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Подскажите, программа состоит из 2 функций (main и fun), программа меняет значение указателя на символьный массив созданный в динамически распределяемой памяти. 
Программ меняет символьный массив "abc" на "cba" ошибок нет. Вопрос в другом, нужно ли удалять указатель из кучи в функции main или fun, не произойдет ли утечка памяти,
не становиться ли указатель str_f из функции fun "диким" при завершении функции fun??? При попытке удалить указатель delete str_f или delete[] str_f, при выполнении программы выходит ошибка. 




Код

#include "stdafx.h"
#include <iostream>
#include <stdlib.h>
#include <conio.h>
#include <stdio.h>
#include <windows.h>

using namespace std;
char* fun()
{
   char* str_f=new char[5];
   ZeroMemory(str_f, 5);
   str_f="cba";
   /* delete str_f;  нужно ли удалять указатель массив char из динамически распределяемой памяти. При выполнении выходит ошибка */
   return str_f; 
}
int _tmain(int argc, _TCHAR* argv[])
{
    
    int n=5;
    char* str=new char[5];
    ZeroMemory(str, 5);
    str="abc";
    cout<<str <<endl;
    str=fun();
    cout<<str <<endl;
    /* delete[] str; нужно ли удалять указатель массив char из динамически распределяемой памяти. При выполнении выходит ошибка */
    cout<<str;
    getch();
    return 0;
    
}

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


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Цитата(polin11 @  8.8.2015,  00:44 Найти цитируемый пост)
char* fun()
{
   char* str_f=new char[5];
   ZeroMemory(str_f, 5);
   /* str_f="cba"; */
   delete str_f;  /* нужно ли удалять указатель массив char из динамически распределяемой памяти. При выполнении выходит ошибка */
   return str_f
}

Вот подумайте сами. Вы высвободите запрошенный массив символов, а указатель на него вернёте из функции. На что будет указывать этот указатель? Он, конечно, будет указывать куда-тов память процесса, но куда? Неизвестно. Указатель стал невалидным, использовать в дальнейшем его категорически нельзя. В этом смысле такой код мало чем отличается от такого:
Код
char* fun()
{
   char str_f[5];
   ZeroMemory(str_f, 5);
   memcpy( str_f, "cba", sizeof("cba"));
   return str_f; 
}


ЗЫ Массив высвобождается через delete [] ..., а не просто delete.


Но что Вы делаете в коде. После выделения участка памяти под массив, Вы изменяете значение указателя:
Цитата(polin11 @  8.8.2015,  00:44 Найти цитируемый пост)
   str_f="cba";

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


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
TarasProger
Дата 12.8.2015, 10:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



polin11, утечка произошла уже в 25-й строке: в 21-й память по указателю была выделена, а адрес, где именно выделена, записано в указателе и нигде больше, потом в 25-й строке указателю присвиваеется значение функции, которая тоже что то выделила и вернула адрес, где именно выделила. Так как указатель поменял свою значение при этом присваивании, то старое значение с адресом выдения в 21-й строке потерялось. Раз ты по этому указателю выделял память, то прежде чем менять его значение, надо память освободить. Совсем другое дело 
Код
char *p;
char *i;
p=new char [256];
i=p;
do
{
 ++i; /*Память выделена по p, а меняется i, это разные указатели, адрес всего блока выделенной
 памяти в p остаётся, i же используется для перебора. В этом случае ничего освобождать не нужно*/
} while ((i-p)<256);
, но и тогда p надо освободить после использования. Если это локальная автоматическая переменная функции и значение этой переменной наружу не выдаётся, то в любом месте функции до её завершения, но не раньше, чем блок выделенной памяти станет не нужен. Если глобальная, то до завершения программы, но опять таки после того, как выделенный блок станет не нужен, а если это переменная, значение которой выдаётся наружу, то где то в вызывающем коде, но опять таки до его завершения, но не раньше, чем сам выделенный блок станет не нужен.

Это сообщение отредактировал(а) TarasProger - 12.8.2015, 10:56
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

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

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


 




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


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

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