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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 12.11.2015, 09:56   #21
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Цитата:
Получается delete [] удалил первый элемент для типа int *. Что меня не устраивает.
Да причем тут delete, до вас уже третью страницу пытаются донести, что nullptr не удаляет ничего, просто вы не сможете использовать этот указатель для обращения к массиву (даже если в том месте памяти все еще лежат те данные) после присваивания ему любого другого значения (nullptr, 0, 111, 888). То есть гарантировано получите exception/assert/или_что_там_выпадает вместо неопределенного поведения (UB) при обращении к указателю после удаления.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.

Последний раз редактировалось Alex11223; 12.11.2015 в 10:05.
Alex11223 вне форума Ответить с цитированием
Старый 12.11.2015, 10:05   #22
chipside
Форумчанин
 
Регистрация: 03.08.2013
Сообщений: 208
По умолчанию

Цитата:
Сообщение от Alex11223 Посмотреть сообщение
Да причем тут delete, до вас уже третью страницу пытаются донести, что nullptr не удаляет ничего, просто вы не сможете использовать этот указатель для обращения к массиву (даже если в том месте памяти все еще лежат те данные) после присваивания ему любого другого значения (nullptr, 0, 111, 888).
Тогда что по вашему способно удалить данные массива и высвободить память из кучи? Простое присвоение нулей не решит проблему с памятью, а только затрёт исходные данные.
chipside вне форума Ответить с цитированием
Старый 12.11.2015, 10:28   #23
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Причем тут освобождение? delete не обязан нулями память заполнять, только помечать как свободную.

Поэтому (в зависимости от реализации компилятора) вполне возможно что там еще останутся старые данные, пока кто-нибудь не занял этот кусок и не затер их.

Но разыменовывать указатель после delete в любом случае не стоит, это неопределенное поведение. Присваивание nullptr/0/... всего лишь делает его определенным — программа гарантированно "упадет". (ну или просто для проверок на нулл если это глобальная переменная какая-нибудь, чтоб выделить память и создать объект заново)
http://rextester.com/SAVZAA11112
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.

Последний раз редактировалось Alex11223; 12.11.2015 в 10:31.
Alex11223 вне форума Ответить с цитированием
Старый 12.11.2015, 10:52   #24
chipside
Форумчанин
 
Регистрация: 03.08.2013
Сообщений: 208
По умолчанию

Цитата:
Сообщение от Alex11223 Посмотреть сообщение
Причем тут освобождение? delete не обязан нулями память заполнять, только помечать как свободную.

Поэтому (в зависимости от реализации компилятора) вполне возможно что там еще останутся старые данные, пока кто-нибудь не занял этот кусок и не затер их.

Но разыменовывать указатель после delete в любом случае не стоит, это неопределенное поведение. Присваивание nullptr/0/... всего лишь делает его определенным — программа гарантированно "упадет". (ну или просто для проверок на нулл если это глобальная переменная какая-нибудь, чтоб выделить память и создать объект заново)
http://rextester.com/SAVZAA11112
И всё таки без затирания остаточных данных или использования nullptr, как альтернативы нельзя отказываться, т.к. delete [] в g++ не удаляет данные из массива, а только первый элемент. К примеру, намедни написал код, который неверно указывал количество символов в файле, до того, как стал затирать "остаточные данные". Тип уже char*
Код:
#include <iostream>
#include <cstdio>
#include <string>

using namespace std;

int main ( int argc, char * argv[]) {
	if ( argc > 2 ) {
		int Count = 0, i = 0;
		char * InputChars;
		const int Max = 1024;
		string yToTellTheNumberOfLines = "Количество строк = ";
		string yToTellTheNumberOfMatches = "Количество совпадений = ";
		
		InputChars = new char[1024];
		// http://cppstudio.com/post/1699/
		FILE * readFile = fopen(argv[2], "r"); 
		
		if (readFile == NULL ) perror("Ошибка открытия файла");
		else {
			int x = 0;
			while ( fgets( InputChars, Max, readFile ) != NULL ) {
				for ( ; x < Max; x++ ) {
					if ( InputChars[x] == argv[1] [0] ) Count++;
				};
				for ( int y = 0; y < x; y++ ) {
					InputChars[y] = ' ';
				};
				i++;
				InputChars[x] = '\0';
				x = 0;
			};
			fclose (readFile);
		};
		
		cout << yToTellTheNumberOfMatches << Count << '.' << endl;
		cout << yToTellTheNumberOfLines << i << '.' << endl;
		
		if ( InputChars[0] ) delete [] InputChars;
		
		return 0;
	} else {
		string yToTellTheErrorMessage = "Неверно указаны праметры программы в командной строке. \
Первым параметром передаётся искомый символ, вторым файл, который нужно проверить. \n\
Параметры разделяются пробелами.";
		cerr << yToTellTheErrorMessage << endl;
	
		return 1;
	};
};
Однако, сведения о том, что delete [] помечает данные, как освобождённые меня обнадёжили. Скажите, что будет, если не использовать delete до завершения программы? После завершения будет зомби-процесс или что? Или память освободится?
--------
Да. Действительно nullptr ничего не затирает! По крайне мере в стандарте x0 компилятора gcc (g++)
Код:
#include <iostream>

using namespace std;

int main ( void ) {

#if __cplusplus<201103L
   #define nullptr (0)
#endif


#ifdef nullptr
    cout << "nullptr" << endl;
    
    int * x;
    x = (int *) nullptr;
    if ( x ) {
    	cout << "x -- истина." << endl;
    } else {
    	cout << "x -- ложь." << endl;
    };
    
    x = new int[10];
    for (int i = 0; i <10; i++) x[i] = 2*i + 4;
    delete [] x;
    for (int i = 0; i <10; i++) cout << x[i] << ' ';
    cout << endl;
    if ( x ) {
    	cout << "x -- истина." << endl;
    } else {
    	cout << "x -- ложь." << endl;
    };
    x = (int *) nullptr;
    x = new int[10];
    for (int i = 0; i <10; i++) cout << x[i] << ' ';
    cout << endl;
#else
    cout << "can not use nullptr" << endl;
#endif

	int* ptr = 0;
	std::cout << *ptr;

    return 0;
}
Вывод:
Код:
nullptr
x -- истина.
0 6 8 10 12 14 16 18 20 22 
x -- истина.
0 6 8 10 12 14 16 18 20 22 
Ошибка сегментирования

Последний раз редактировалось chipside; 12.11.2015 в 10:59.
chipside вне форума Ответить с цитированием
Старый 12.11.2015, 11:10   #25
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,709
По умолчанию

Вам уже 100 раз сказали нуллпоинтер - это просто спец. константа для указателей (такая же как и 11111, или 2222, или 4444, или 901901234984011470).
Она затирает только значение указателя, к данным по этому указателю она никак не относится, совсем.

Цитата:
delete [] в g++ не удаляет данные из массива, а только первый элемент
delete [] удаляет массив, но не затирает данные в нем.. даже первый элемент. Просто вам повезло и ОС отдала эту память уже кому-то и кто-то затер вам первый элемент.

Код:
if ( InputChars[0] ) delete [] InputChars;
Кстати, что это за проверка? Что вы этим хотели сказать? Удаляете массив только если 0-й элемент отличен от нуля?

Последний раз редактировалось p51x; 12.11.2015 в 11:19.
p51x вне форума Ответить с цитированием
Старый 12.11.2015, 11:15   #26
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
И всё таки без затирания остаточных данных или использования nullptr, как альтернативы нельзя отказываться, т.к. delete [] в g++ не удаляет данные из массива, а только первый элемент. К примеру, намедни написал код, который неверно указывал количество символов в файле, до того, как стал затирать "остаточные данные". Тип уже char*
он не очищает память.
представьте что память это лист линейной бумаги.
вы запросили пять первых линий, исписали их, потом сказали что они вам больше не нужны.
но если вы лезите у этим 5 линиям, думаете ваши данные куда-то делись от этого?
нет, то что писалось так и останется. а менеджер память вернет этот лист только когда он весь не нужен будет, а не оторвет ваши 5 строчек.
обратится можно и по рандомному указателю, и если попадете где есть данные, то вы их прочтете.
нулевой указатель(nullptr,0,NULL) это указатель который гарантировано не читается. потому и будет ошибка.(кстати с указателем 0x00000001 у вам тоже прога упадет, но он же не nullptr)
nullptr/0/NULL просто индикация что указатель невалиден.
Цитата:
Скажите, что будет, если не использовать delete до завершения программы?
память останется за вами, если делать много new(не возвращая память обратно) память кончится
Цитата:
После завершения будет зомби-процесс или что? Или память освободится?
зомби процесс это иное.
ОС обычно вернет ресурсы, но это не хорошо в общем-то.
Цитата:
Да. Действительно nullptr ничего не затирает! По крайне мере в стандарте x0 компилятора gcc (g++)
и ни в каком ином стандарте не будет, если вам надо затереть ту память(например там были конфиденциальные данные) то делайте это ручками перед delete.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 12.11.2015, 11:17   #27
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Чот с вами бесполезно общаться, вы не читаете/не понимаете и делаете какие-то странные выводы на основе своих обрывков знаний. Откуда-то придумали про какую-то альтернативу и отказ.

Код выше странный, непонятно почему вы решили, что заполнение строки пробелами чем-то поможет, и \0 вроде и так fgets добавляется, но вы как минимум присваиваете \0 в несуществующий 1025-й элемент.

nullptr от 0/NULL отличается например в ситуации когда есть перегрузка функции для int и для указателя (char*, int*, WhatEver*)
http://stackoverflow.com/questions/1...-using-nullptr

Цитата:
Скажите, что будет, если не использовать delete до завершения программы? После завершения будет зомби-процесс или что? Или память освободится?
Освободится при завершении процесса. Если не освобождать память, то проблема (нехватка памяти) может возникнуть если программа долго работает и постоянно забирает память, для хеллоуворлдов работающих полсекунды не имеет значения.
Зомби-процессы это вообще не о том.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.

Последний раз редактировалось Alex11223; 12.11.2015 в 11:22.
Alex11223 вне форума Ответить с цитированием
Старый 12.11.2015, 11:25   #28
chipside
Форумчанин
 
Регистрация: 03.08.2013
Сообщений: 208
По умолчанию

Спасибо всем, кто принял участие в обсуждении. До меня, наконец-то дошло!
chipside вне форума Ответить с цитированием
Старый 12.11.2015, 14:57   #29
Croessmah
Вредный кошак
Участник клуба
 
Аватар для Croessmah
 
Регистрация: 14.10.2012
Сообщений: 1,159
По умолчанию

Цитата:
Освободится при завершении процесса
Добавлю, что все ресурсы будут просто "прихлопнуты" операционкой, и никакие деструкторы вызваны не будут, соответственно могут быть какие-то побочные эффекты, например, потеряны какие-то данные, или отсутствие соответствующих записей в логах и т.д.
Croessmah вне форума Ответить с цитированием
Старый 12.11.2015, 15:18   #30
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Да какие деструкторы если он почти на чистом Си пишет. Из С++ тут кроме std::cout особо ничего нет
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
26|error: 'nullptr' was not declared in this scope| taras-proger Общие вопросы C/C++ 2 08.09.2015 14:02
Определить по коду алгоритм сортировки и исправить специально допущенные в коде ошибки ( Turbo Delphi ) Just-Joni Помощь студентам 0 26.12.2013 12:24
Не получается найти ошибку в коде нужно определить размеры дисков C++ Borland kolyok333 Помощь студентам 4 15.01.2012 15:53
Cuda, openCL: как определить, есть ли поддержка xpu Visual C++ 1 27.08.2011 03:36
Поддержка казахского языка. Как? eremin Общие вопросы Delphi 1 01.12.2007 06:30