Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.06.2011, 01:04   #1
ImmortalAlexSan
Участник клуба
 
Аватар для ImmortalAlexSan
 
Регистрация: 13.01.2009
Сообщений: 1,353
По умолчанию Нужно удалить указатель на массив - на строке с delete вылетает Debug Error.

Привет всем в очередной раз
Код:
bool DeletePointer(WCHAR* pPointer)
{
	if (pPointer != NULL) {
		delete [] pPointer;
		pPointer = NULL;
		return true;
	}
	else
		return false;
};
Пытаюсь вот таким макаром удалить указатель на массив. Смотрю в дебагере: pPointer принимает нужное значение и инфа в *pPointer хранится соответствующая. Но на строке с delete вылетает Debug Error. Может быть, я не правильно передаю указатель в функцию? Пробовал и указатель на указатель передавать, ничего не меняется.
А вот такое удаление работает нормально:
Код:
bool DeletePointer(WCHAR** pPointer)
{
	if (*pPointer != NULL) {
		delete pPointer;
		*pPointer = NULL;
		return true;
	}
	else
		return false;
};
Но что-то я не понимаю, что в данном случае удаляется? Созданный функцией указатель удаляется?
"Тебе то может на меня и насрать, но твои глаза меня обожают!"
ImmortalAlexSan вне форума Ответить с цитированием
Старый 07.06.2011, 06:37   #2
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию

Как минимум в первом случае вы не сможете присвоить указателю значение NULL (или какое-то другое), т.к. переменную типа "указатель на WCHAR" вы передаете по значению, и этой переменной нельзя присвоить никакое новое значение (можно только локальной копии, которая будет уничтожена при выходе из функции - а это бессмысленно).
Во втором случае у вас тоже ошибка - вы передаете переменную "указатель на WCHAR" по указателю и присваиваете ей NULL корректно, однако для удаления массива необходимо вызвать delete[] для указателя на массив, т.е. нужна такая строчка:
Код:
delete[] (*pPointer);
Еще один вариант - т.к. указатель тоже является переменной, то эту переменную можно передавать не только по указателю, но и по ссылке. Фактически получится почти то же, что и в первом варианте:
Код:
bool DeletePointer((WCHAR*)& pPointer)   //Ссылка на переменную типа WCHAR*
{
	if (pPointer != NULL) {
		delete [] pPointer;
		pPointer = NULL;
		return true;
	}
	else
		return false;
};
Не уверен, что это гарантированно поможет, но так будет хотя бы меньше ошибок
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 07.06.2011, 07:38   #3
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,119
По умолчанию

ImmortalAlexSan

Но на строке с delete вылетает Debug Error.

А вот такое удаление работает нормально:

Забавный все таки язык программирования C++. Вот есть два кода - один корректный, другой - говнокод. Но при этом первый вызывает ошибку, а второй отрабатывает нормально (((:

Может быть, я не правильно передаю указатель в функцию?

ты неправильно выделаешь память и/или работаешь с ней.
Rififi вне форума Ответить с цитированием
Старый 07.06.2011, 08:01   #4
profi
Участник клуба Подтвердите свой е-майл
 
Регистрация: 19.11.2007
Сообщений: 1,022
По умолчанию

ImmortalAlexSan, код правильный. Может ты не правильно передаешь. Вот быстро набросал, правда я не WCHAR юзал.

Код:
#include <iostream>
#include <string.h>

bool DeletePointer(char *&pPointer)
{
	if (pPointer != NULL) {
		delete [] pPointer;
		pPointer = NULL;
		return true;
	}
	else
		return false;
}

int main()
{
    char *buff = new char[255];

    strcpy(buff, "Hello");

    std::cout << buff << "\n";

    std::cout << DeletePointer(buff);

    return 0;
}

Последний раз редактировалось profi; 07.06.2011 в 18:00.
profi вне форума Ответить с цитированием
Старый 07.06.2011, 08:09   #5
ImmortalAlexSan
Участник клуба
 
Аватар для ImmortalAlexSan
 
Регистрация: 13.01.2009
Сообщений: 1,353
По умолчанию

Гром, bool DeletePointer((WCHAR*)& pPointer), компилятор не пропускает, подчеркивает.
delete[] (*pPointer); - с этим такая же канитель.
Если ошибка лежит глубже, то я с памятью работаю и выделяю её в одной лишь функции:
Код:
void SetNodeField(WCHAR* pSource, WCHAR** pTaker)
{
	WCHAR* PtrS = pSource;
	unsigned char i = 0;
	unsigned char j = 0;

	DeletePointer(pTaker);
	if (*pTaker != NULL) {
		delete [] *pTaker;
		*pTaker = NULL;
	}
	while (*PtrS != '\0') {
		j++;
		PtrS++;
	};
	PtrS = pSource;
	*pTaker = new WCHAR[j];
	for (i = 0; i <= j; i++) {
		(*pTaker)[i] = *PtrS;
		if (i != j)
			PtrS++;
	};
};
После этого я могу вывести данные, что лежат по нужному адресу нормально.
И кстати, после выпадения ошибки дебагера, жму "пропустить", и прога работает дальше корректно))) Опять всё нормально считывается из памяти.
profi, попробовал вызвать функцию не из функции, а из основного кода, - такая же хрень.
"Тебе то может на меня и насрать, но твои глаза меня обожают!"

Последний раз редактировалось ImmortalAlexSan; 07.06.2011 в 08:14.
ImmortalAlexSan вне форума Ответить с цитированием
Старый 07.06.2011, 08:18   #6
profi
Участник клуба Подтвердите свой е-майл
 
Регистрация: 19.11.2007
Сообщений: 1,022
По умолчанию

ImmortalAlexSan ну теперь ясно . Ты же не правильно указатель удаляешь. Ты в функцию передавал массив указателей.

Сигнатура функции:
Код:
bool DeletePointer(WCHAR* pPointer)
Передаешь:
Код:
WCHAR** pTaker
Ниче не смущает?
Код:
bool DeletePointer(WCHAR** pPointer)
{
	if (*pPointer != NULL) {
		delete pPointer;
		*pPointer = NULL;
		return true;
	}
	else
		return false;
}
Этот код работал правильно, так как ты удалял указатель, который является первым элементом массива указателей pPointer. Здесь нужно циклом под массив указателей выделить память, а потом циклом её освободить.
Вот исправил, как то так:
Код:
#include <iostream>
#include <string.h>

bool DeletePointer(char **&pPointer)
{
    for(int i = 0; i < 3; i++)
    {
        if(pPointer[i] != NULL)
        {
            delete []pPointer[i];
            pPointer[i] = NULL;
        }
    }

	if (pPointer != NULL) {
		delete []pPointer;
		pPointer = NULL;
		return true;
	}
	else
		return false;
}

int main()
{
    char **buff;
    buff = new char*[3];
    for(int i = 0; i < 3; i++)
        buff[i] = new char[255];

    std::cout << DeletePointer(buff);

    return 0;
}

Последний раз редактировалось profi; 07.06.2011 в 18:01.
profi вне форума Ответить с цитированием
Старый 07.06.2011, 14:44   #7
ImmortalAlexSan
Участник клуба
 
Аватар для ImmortalAlexSan
 
Регистрация: 13.01.2009
Сообщений: 1,353
По умолчанию

profi, у меня не двумерный массив... У меня просто
Код:
char *buff;
P.S. Создал новый проект, написал там:
Код:
bool DeletePointer(char *pPointer)
{
	if (pPointer != NULL) {
		delete []pPointer;
		pPointer = NULL;
		return true;
	}
	else
		return false;
}

int _tmain(int argc, _TCHAR* argv[])
{
    char *buff;
    buff = new char[3];
    std::cout << DeletePointer(buff);
    std::cin.get();
    return 0;
}
Всё работает как надо... Но buff не обнуляется... Щас указатель на buff передам, посмотрим. Передал указатель. Вс работает как надо) Но это не совсем та структура, что в другом проекте... Щас поробую реализовать.
"Тебе то может на меня и насрать, но твои глаза меня обожают!"

Последний раз редактировалось ImmortalAlexSan; 07.06.2011 в 14:55.
ImmortalAlexSan вне форума Ответить с цитированием
Старый 07.06.2011, 14:51   #8
profi
Участник клуба Подтвердите свой е-майл
 
Регистрация: 19.11.2007
Сообщений: 1,022
По умолчанию

Код:
void SetNodeField(WCHAR* pSource, WCHAR** pTaker)
{
	WCHAR* PtrS = pSource;
	unsigned char i = 0;
	unsigned char j = 0;

	DeletePointer(pTaker);
Я указал примерный путь как исправить ошибку по листингу, который ты привел. Дерзай. Я же не видел твой код полностью. Мой пример в посте #4 полностью правильный.
profi вне форума Ответить с цитированием
Старый 07.06.2011, 14:57   #9
ImmortalAlexSan
Участник клуба
 
Аватар для ImmortalAlexSan
 
Регистрация: 13.01.2009
Сообщений: 1,353
По умолчанию

profi, спасибо огромное вам! Я кажется понял в чем ошибка. С удалением указателя в функции придется работать как с двумерным динамич. массивом, сейчас проверю довод... Сначала проверил так:
Код:
struct Second
{
	WCHAR* text;
};

struct First
{
	Second* second;
};

First* GetPtr()
{
	First* first = new First();
	first->second = new Second();
	first->second->text = new WCHAR[10];
	return first;
};

bool DeletePointer(WCHAR** pPointer)
{
	if (*pPointer != NULL) {
		delete [] *pPointer;
		*pPointer = NULL;
		return true;
	}
	else
		return false;
}

int _tmain(int argc, _TCHAR* argv[])
{
    First* first;
    first = GetPtr();
	std::cout << DeletePointer(&first->second->text);
	std::cin.get();
    return 0;
}
Всё работает как по маслу - без ошибок по крайней мере. Правильно я сделал? Всю память, что выделял под тип WCHAR освободил? Как проверить утечку ребят?
"Тебе то может на меня и насрать, но твои глаза меня обожают!"

Последний раз редактировалось ImmortalAlexSan; 07.06.2011 в 15:15.
ImmortalAlexSan вне форума Ответить с цитированием
Старый 07.06.2011, 15:55   #10
profi
Участник клуба Подтвердите свой е-майл
 
Регистрация: 19.11.2007
Сообщений: 1,022
По умолчанию

Огогого сколько указателей . Кстати сделай лучше так:

Код:
bool DeletePointer(WCHAR*& pPointer)
{
	if (pPointer != NULL) {
		delete [] pPointer;
		pPointer = NULL;
		return true;
	}
	else
		return false;
}
........
std::cout << DeletePointer(first->second->text);
P.S. Просто так понятней будет.

Последний раз редактировалось profi; 07.06.2011 в 17:52.
profi вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
нужно написать программу в debug melkaya9112 Помощь студентам 1 09.12.2010 01:01
Visual Studio 2010, при запуске на debug или rebuild вылетает ошибка Evgeniy1989 Общие вопросы .NET 1 20.08.2010 08:34
error C2541: 'delete' : cannot delete objects that are not pointers novokhatsky Общие вопросы C/C++ 2 14.12.2009 10:25
LIBCD.lib(crt0.obj) : error LNK2001: unresolved external symbol _main Debug/main.exe : fatal error LNK11 prefak Win Api 0 19.04.2009 16:51
Debug/DLL10.dll : fatal error LNK1136: invalid or corrupt file AHJLPeu* Общие вопросы C/C++ 2 23.10.2008 20:59