Сообщение от argcargv
Т.е. ты несёшь неизвестно откуда взявшуюся чушь, а другие должны бегать и искать откуда ты её берёшь?
нет никаких «т.е.»
ты сделал вывод исходя из собственных фантазий своего бреда.
а мои тезисы опираются на стандарт,
в частности, опираются на материал, доступный по ссылкам, который ты привел в #2
и самое главное: подтверждаются реальной практикой.
Сообщение от argcargv
Да, invalid pointer value не обязательно единственное значение. Их неопределённое число.
это не просто «не обязательно единственное значение» — это вообще не конкретное значение.
любое значение может стать «invalid pointer value».
одно и тоже значение: сегодня ещё валидное, а завтра уже не_валидное.
Сообщение от argcargv
Ну тупишь пока только ты, называя значение характеристикой значения.
нет тупишь ты, называя характеристику значения значением.
и отсюда всё дальнейшее непонимание сабжа с твоей стороны.
Сообщение от argcargv
считаю что в C++ происходит запись в указатель только потому что я прочитал что так считают сишники.
ну значит ты тупее, чем я думал.
нормальные люди делают выводы на основании фактов,
а не на основании мнения черт-знает-кого, черт-знает-о-чем.
но даже если принять за истину тезис, что зомби-указатели чего то там должны.
что с того?
это не даёт тебе никаких оснований считать,
что на самом деле происходит с указателями с++.
твои горячо любимые сишники нигде не писали, что в с++ по указателю происходит какая то запись.
так с какого фига ты сделал такой вывод?
эй ау, у тебя какие то проблемы с логикой?
Сообщение от argcargv
Нет такого значения, как «адрес объекта». Есть «указатель на объект».
такое впечатление, что ты деградируешь.
раньше ты настолько тупым не был.
указатель на объект — это тип данных.
его значение — адрес объекта.
я сейчас напишу фразу, которую без труда сможет понять любой,
даже начинающий программист с++:
нужно взять адрес объекта, и поместить его в указатель
теоретически: даже ты должен суметь понять.
Сообщение от argcargv
Мне вполне понятна элементарная вещь: в теме значений указателей ты плаваешь.
моя скоромная персона тебя вообще касаццо не должна.
ты со своими мозгами разберись для начала.
ты уже понял, что такое «валидный указатель» ?
Сообщение от argcargv
Еды тебе больше не будет. Можешь продолжать нести чушь сколько угодно.
обязательно расскажи про это своему психиатру.
заодно расскажи ему,
что ты таки проигнорировал объективную реальность (код #11),
ведь она противоречит твоей шизоидной теории.
Your copy constructor does a shallow copy. So, now you have two objects that both have the same recording
pointer.
You should either do a deep copy, or ensure the ownership is properly transferred (by using something like std::unique_ptr<Recording>
if C++11
is available.
See This question on the difference between deep and shallow copies.
Let’s look at some examples:
class ABadCopyingClass
{
public:
ABadCopyingClass()
{
a_ = new int(5);
}
~ABadCopyingClass()
{
delete a_;
}
private:
int* a_;
};
The above class is bad because the default copy constructor and assignment operator will perform a shallow copy, and lead to two objects both thinking that they own the underlying a_
object. When one of them goes out of scope, the a_
will be deleted, and the other one will be left with a dangling pointer that will eventually lead to a crash.
class ABetterCopyingClass
{
public:
ABetterCopyingClass()
a_(new int(5))
{
}
ABetterCopyingClass(const ABetterCopyingClass& r)
{
a_ = new int(*r.a_);
}
ABetterCopyingClass& operator=(const ABetterCopyingClass& r)
{
// in the case of reassignment...
delete a_;
a_ = new int(*r.a_);
return *this;
}
~ABetterCopyingClass()
{
delete a_;
}
private:
int* a_;
};
This class improved our situation a little (note, that the normal error checking is left out in this simple example). Now the copy constructor and assignment operator properly perform the necessary deep copying. The drawback here is the amount of boilerplate code we had to add — it’s easy to get that wrong.
class ACannonicalCopyingClass
{
public:
ACannonicalCopyingClass()
: a_(new int(5))
{
}
ACannonicalCopyingClass(ACannonicalCopyingClass&& moved_from)
{
a_ = std::move(moved_from.a_);
}
private:
std::unique_ptr<int> a_;
};
This example (C++11 only) is even better. We’ve removed a significant amount of boilerplate code, however the semantics here are a bit different. Instead of deep copying, we get in this case transfer of ownership of the underlying a_
object.
The easiest version (C++11 only) to implement is the version that provides shared ownership of the underlying a_
object. This is the version that is most similar to your provided example, with the added bonus that it does not cause a crash.
class ASharedCopyingClass
{
public:
ASharedCopyingClass()
: a_(std::make_shared<int>(5))
{
}
private:
std::shared_ptr<int> a_;
};
This version can be copied at will, and the underlying a_
object will happily be reference counted. The last copy to go out of scope will set the reference count to 0
, which will trigger the memory deallocation.
Я изучил C ++ в онлайн-курсе, но у меня возникла проблема с оператором «delete» в Visual Studio. Когда удаление выполняется, он открывает файл delete_scalar.cpp
и показывает:
ConsoleApplication.exe вызвал точку останова. исключение
Я уже перемещаю папку SymbolCache из temp, включая wntdll.pdb и т. Д.
#include "pch.h"#include <iostream>
using namespace std;
int main()
{
int *pInt = new int;
*pInt = 3;
cout << *pInt << endl;
cout << pInt << endl;
delete[] pInt; //error -- UPDATED: still get error with `delete pInt;`
return 0;
}
здесь информация о выходе,
«ConsoleApplication11.exe» (Win32): загружен «C: \ Windows \ SysWOW64 \ ntdll.dll». Символы загружены.
«ConsoleApplication11.exe» (Win32): загружен «C: \ Windows \ SysWOW64 \ kernel32.dll». Символы загружены.
«ConsoleApplication11.exe» (Win32): загружен «C: \ Windows \ SysWOW64 \ KernelBase.dll». Символы загружены.
«ConsoleApplication11.exe» (Win32): загружен «C: \ Windows \ SysWOW64 \ msvcp140d.dll». Символы загружены.
«ConsoleApplication11.exe» (Win32): загружен «C: \ Windows \ SysWOW64 \ vcruntime140d.dll». Символы загружены.
«ConsoleApplication11.exe» (Win32): загружен «C: \ Windows \ SysWOW64 \ ucrtbased.dll». Символы загружены.
Поток 0x2fd0 вышел с кодом 0 (0x0).
HEAP [ConsoleApplication11.exe]: неверный адрес, указанный для RtlValidateHeap (00930000, 009359E8)
ConsoleApplication11.exe вызвал точку останова.
delete_scalar.cpp из самого визуала,
//
// delete_scalar.cpp
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Defines the scalar operator delete.
//
#include <crtdbg.h>
#include <malloc.h>
#include <vcruntime_new.h>
#include <vcstartup_internal.h>
_CRT_SECURITYCRITICAL_ATTRIBUTE
void __CRTDECL operator delete(void* const block) noexcept
{
#ifdef _DEBUG
_free_dbg(block, _UNKNOWN_BLOCK); // the circle X symbol showed up there
#else
free(block);
#endif
}
Я уже делаю точки останова, такие как включение и удаление, но точка останова все еще срабатывает на delete_scalar.cpp с отображением символа X круга.
0
Решение
Если вы попросите памяти с new
необходимо удалить с помощью delete
,
Использовать только delete [ ]
когда ты использовал new [ ]
, Несовпадение двух приводит к неопределенному поведению.
2
Другие решения
Других решений пока нет …
Hi Fellow Programmers!
I am having some trouble with this small project.
I am getting a exception thrown at me from «delete_scalar.cpp:Line 34: _free_dbg(block, _UNKNOWN_BLOCK);»
Which stems from me trying to delete a pointer holding a char array.
Here is context
The Destructor
Menu::~Menu() { //Deallocate title delete[] m_title; //Deallocate menu items if (m_menuCount > 0) { for (int i = 0; i < m_menuCount; i++) { delete m_menuItem[i]; m_menuItem[i] = nullptr; } } //Initialize values m_menuCount = 0; m_indentation = 0; }
Here is the declarations of the objects
Menu mainMenu("** Main Menu **"); Menu subMenu1("** Sub Menu One **", 1); Menu subMenu2("** Sub Menu **", 2); Menu tempMenu("** Temp **"); Menu invMenu("** To test Invalid Menu **");
When the client code completes and the destructors start deleting the pointers, once the destructor hits subMenu2 it throws the exception, invMenu and tempMenu destruct first and no errors there.
Here is the values right at return 0, before destructors get called.
- invMenu {m_title=0x009c5248 "" m_menuItem=0x0077f718 {0x00000000 <NULL>, 0x00000000 <NULL>, 0x00000000 <NULL>, ...} ...} sdds::Menu - m_title 0x009c5248 "" char * 0 '\0' char + m_menuItem 0x0077f718 {0x00000000 <NULL>, 0x00000000 <NULL>, 0x00000000 <NULL>, 0x00000000 <NULL>, 0x00000000 <NULL>, ...} sdds::MenuItem *[11] m_menuCount 0 int m_indentation 0 int - mainMenu {m_title=0x009c8f78 "" m_menuItem=0x0077f818 {0x009cfeb8 {m_item=0xdddddddd <Error reading characters of string.> }, ...} ...} sdds::Menu - m_title 0x009c8f78 "" char * 0 '\0' char + m_menuItem 0x0077f818 {0x009cfeb8 {m_item=0xdddddddd <Error reading characters of string.> }, 0x009d0128 {m_item=...}, ...} sdds::MenuItem *[11] m_menuCount 0 int m_indentation 0 int - subMenu1 {m_title=0x009c6200 "" m_menuItem=0x0077f7d8 {0x009cffa8 {m_item=0xdddddddd <Error reading characters of string.> }, ...} ...} sdds::Menu - m_title 0x009c6200 "" char * 0 '\0' char + m_menuItem 0x0077f7d8 {0x009cffa8 {m_item=0xdddddddd <Error reading characters of string.> }, 0x009d0188 {m_item=...}, ...} sdds::MenuItem *[11] m_menuCount 0 int m_indentation 0 int - subMenu2 {m_title=0x009c9258 "** Sub Menu **" m_menuItem=0x0077f798 {0x009d0158 {m_item=0x009ce298 "The first" }, ...} ...} sdds::Menu - m_title 0x009c9258 "** Sub Menu **" char * 42 '*' char + m_menuItem 0x0077f798 {0x009d0158 {m_item=0x009ce298 "The first" }, 0x009cffd8 {m_item=0x009ce7a0 "The second" }, ...} sdds::MenuItem *[11] m_menuCount 3 int m_indentation 2 int - tempMenu {m_title=0x009d1de0 "** Sub Menu **" m_menuItem=0x0077f758 {0x009d0008 {m_item=0x009ce6f8 "The first" }, ...} ...} sdds::Menu - m_title 0x009d1de0 "** Sub Menu **" char * 42 '*' char + m_menuItem 0x0077f758 {0x009d0008 {m_item=0x009ce6f8 "The first" }, 0x009cfee8 {m_item=0x009ce650 "The second" }, ...} sdds::MenuItem *[11] m_menuCount 3 int m_indentation 2 int
Apologizes I cant post images yet….
Also the only time subMenu2 gets interacted with is when adding menu options here
subMenu2 << "The first" << "The second" << "The third";
and the code for the adding here
Menu& Menu::operator<<(const char* item) { if (*this) { if (item != nullptr && item[0] != '\0') { //Add the item add(item); } else { //Set title to safe state m_title[0] = '\0'; } } //Return object return *this; } void Menu::add(const char* item) { if (item != nullptr && item[0] != '\0') { //Check we are valid and are not exceeding max if (m_menuCount < MAX_NO_OF_ITEMS && *this) { m_menuItem[m_menuCount] = new MenuItem(item); m_menuCount++; } } else { //Set to safe state m_title[0] = '\0'; //Reset values, if title is nullptr then items have been nulled m_menuCount = 0; m_indentation = 0; } }
Any help would be appreciated, it’s confusing because the values show its a normal pointer pointing to a char array identical to invMenu().
Thanks in advances, best wishes!
Сообщение от argcargv
Т.е. ты несёшь неизвестно откуда взявшуюся чушь, а другие должны бегать и искать откуда ты её берёшь?
нет никаких «т.е.»
ты сделал вывод исходя из собственных фантазий своего бреда.
а мои тезисы опираются на стандарт,
в частности, опираются на материал, доступный по ссылкам, который ты привел в #2
и самое главное: подтверждаются реальной практикой.
Сообщение от argcargv
Да, invalid pointer value не обязательно единственное значение. Их неопределённое число.
это не просто «не обязательно единственное значение» — это вообще не конкретное значение.
любое значение может стать «invalid pointer value».
одно и тоже значение: сегодня ещё валидное, а завтра уже не_валидное.
Сообщение от argcargv
Ну тупишь пока только ты, называя значение характеристикой значения.
нет тупишь ты, называя характеристику значения значением.
и отсюда всё дальнейшее непонимание сабжа с твоей стороны.
Сообщение от argcargv
считаю что в C++ происходит запись в указатель только потому что я прочитал что так считают сишники.
ну значит ты тупее, чем я думал.
нормальные люди делают выводы на основании фактов,
а не на основании мнения черт-знает-кого, черт-знает-о-чем.
но даже если принять за истину тезис, что зомби-указатели чего то там должны.
что с того?
это не даёт тебе никаких оснований считать,
что на самом деле происходит с указателями с++.
твои горячо любимые сишники нигде не писали, что в с++ по указателю происходит какая то запись.
так с какого фига ты сделал такой вывод?
эй ау, у тебя какие то проблемы с логикой?
Сообщение от argcargv
Нет такого значения, как «адрес объекта». Есть «указатель на объект».
такое впечатление, что ты деградируешь.
раньше ты настолько тупым не был.
указатель на объект — это тип данных.
его значение — адрес объекта.
я сейчас напишу фразу, которую без труда сможет понять любой,
даже начинающий программист с++:
нужно взять адрес объекта, и поместить его в указатель
теоретически: даже ты должен суметь понять.
Сообщение от argcargv
Мне вполне понятна элементарная вещь: в теме значений указателей ты плаваешь.
моя скоромная персона тебя вообще касаццо не должна.
ты со своими мозгами разберись для начала.
ты уже понял, что такое «валидный указатель» ?
Сообщение от argcargv
Еды тебе больше не будет. Можешь продолжать нести чушь сколько угодно.
обязательно расскажи про это своему психиатру.
заодно расскажи ему,
что ты таки проигнорировал объективную реальность (код #11),
ведь она противоречит твоей шизоидной теории.
Your copy constructor does a shallow copy. So, now you have two objects that both have the same recording
pointer.
You should either do a deep copy, or ensure the ownership is properly transferred (by using something like std::unique_ptr<Recording>
if C++11
is available.
See This question on the difference between deep and shallow copies.
Let’s look at some examples:
class ABadCopyingClass
{
public:
ABadCopyingClass()
{
a_ = new int(5);
}
~ABadCopyingClass()
{
delete a_;
}
private:
int* a_;
};
The above class is bad because the default copy constructor and assignment operator will perform a shallow copy, and lead to two objects both thinking that they own the underlying a_
object. When one of them goes out of scope, the a_
will be deleted, and the other one will be left with a dangling pointer that will eventually lead to a crash.
class ABetterCopyingClass
{
public:
ABetterCopyingClass()
a_(new int(5))
{
}
ABetterCopyingClass(const ABetterCopyingClass& r)
{
a_ = new int(*r.a_);
}
ABetterCopyingClass& operator=(const ABetterCopyingClass& r)
{
// in the case of reassignment...
delete a_;
a_ = new int(*r.a_);
return *this;
}
~ABetterCopyingClass()
{
delete a_;
}
private:
int* a_;
};
This class improved our situation a little (note, that the normal error checking is left out in this simple example). Now the copy constructor and assignment operator properly perform the necessary deep copying. The drawback here is the amount of boilerplate code we had to add — it’s easy to get that wrong.
class ACannonicalCopyingClass
{
public:
ACannonicalCopyingClass()
: a_(new int(5))
{
}
ACannonicalCopyingClass(ACannonicalCopyingClass&& moved_from)
{
a_ = std::move(moved_from.a_);
}
private:
std::unique_ptr<int> a_;
};
This example (C++11 only) is even better. We’ve removed a significant amount of boilerplate code, however the semantics here are a bit different. Instead of deep copying, we get in this case transfer of ownership of the underlying a_
object.
The easiest version (C++11 only) to implement is the version that provides shared ownership of the underlying a_
object. This is the version that is most similar to your provided example, with the added bonus that it does not cause a crash.
class ASharedCopyingClass
{
public:
ASharedCopyingClass()
: a_(std::make_shared<int>(5))
{
}
private:
std::shared_ptr<int> a_;
};
This version can be copied at will, and the underlying a_
object will happily be reference counted. The last copy to go out of scope will set the reference count to 0
, which will trigger the memory deallocation.
|
|
|
Правила раздела Visual C++ / MFC / WTL (далее Раздела)
что значит SomeClass::`scalar deleting destructor'()?
- Подписаться на тему
- Сообщить другу
- Скачать/распечатать тему
|
|
прога у меня вылетает с ошибкой: Цитата Windows has triggered a breakpoint in Magicsd.exe. This may be due to a corruption of the heap, and indicates a bug in Magicsd.exe or any of the DLLs it has loaded. The output window may have more diagnostic information как я понимаю, из-за двойного delete (если неправильно понимаю, прошу поправить) при этом в окне Call Stack встречается строка Цитата Magicsd.exe!MGuiProfileMagics::`scalar deleting destructor'() + 0x33 bytes причем при попытке перехода на нее говорится, что сорс-кода для нее нет и предлагает окунуться в асм. Что это за зверь такой? |
Cartman |
|
Member Рейтинг (т): 1 |
Скорее всего неправильная работа с динамической памятью — всем new должны соответствовать свои delete |
Hsilgos |
|
Alek86 |
Alek86 |
|
Hsilgos, то есть это обычный деструктор? |
Hryak |
|
Цитата Alek86 @ 25.03.08, 07:57 то есть это обычный деструктор?
Это не обычный деструктор (я уже писал тут, но сообщение куда-то пропало. ) |
Alek86 |
|
ясно, спасибо |
0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
0 пользователей:
- Предыдущая тема
- Visual C++ / MFC / WTL
- Следующая тема
[ Script execution time: 0,0226 ] [ 16 queries used ] [ Generated: 28.01.23, 18:01 GMT ]
Задача программы: считать из файла строку, каждое слово из которой необходимо присвоить отдельному элементу массива. Далее, найти 3 самых длинных и 3 самых коротких слова, а затем вывести все слова в порядке, обратном алфавитному. Все задачи написанная мною программа решает, но я не могу очистить память. Проблема в куске программы, в котором элементам массива b присваивается строка из переменной token (все это в цикле while). Именно после сей действия не получается воспользоваться delete[]. Все массивы уже сделал одной размерности, но все равно не помогло. В чем может быть проблема? Код прилагаю ниже. Заранее спасибо!
#define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
#include <stdlib.h>
#include <stdbool.h>
#include <iostream>
#include <locale.h>
#include <windows.h>
#include <ctype.h>
#include <fstream>
#include <malloc.h>
#include <conio.h>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;
void bigswap(int i, int len, int biggest[]) {
if (len > biggest[0]) {
biggest[4] = biggest[2];
biggest[5] = biggest[3];
biggest[2] = biggest[0];
biggest[3] = biggest[1];
biggest[0] = len;
biggest[1] = i - 1;
}
else {
if (len > biggest[2]) {
biggest[4] = biggest[2];
biggest[5] = biggest[3];
biggest[2] = len;
biggest[3] = i - 1;
}
else {
if (len > biggest[4]) {
biggest[4] = len;
biggest[5] = i - 1;
}
}
}
}
void littleswap(int i, int len, int little[]) {
if (len < little[0]) {
little[4] = little[2];
little[5] = little[3];
little[2] = little[0];
little[3] = little[1];
little[0] = len;
little[1] = i - 1;
}
else {
if (len < little[2]) {
little[4] = little[2];
little[5] = little[3];
little[2] = len;
little[3] = i - 1;
}
else {
if (len < little[4]) {
little[4] = len;
little[5] = i - 1;
}
}
}
}
void gettext(char **b, int kolslov) {
printf("Слова, выведенные в порядке, обратном алфавитному:nn");
for (int i = 0; i < kolslov; i++) {
printf("%sn", b[i]);
}
printf("nn");
}
void minusswap(char **b, int kolslov) {
for (int i = 0; i < (kolslov - 1); i++) {
for (int j = i + 1; j < kolslov; j++) {
if ((int)b[i][0] < 91) {
b[i][0] = (char)((int)b[i][0] + 32);
}
if ((int)b[j][0] < 91) {
b[j][0] = (char)((int)b[j][0] + 32);
}
if (strcmp(b[i], b[j]) < 0) swap(b[i], b[j]);
}
}
}
void initialization(int biggest[], int little[]) {
for (int i = 0; i < 6; i++) {
biggest[i] = -1;
little[i] = 100;
}
}
int main() {
char **b, *buffer, *token, delims[] = " n.,!?/<>|)(*:;"";
const int len_text = 300;
int max_len = 0, size_len = 0, Nslov = 0, kolslov = 0, menu = 0;
int biggest[6], little[6];
FILE *load = NULL;
setlocale(LC_ALL, "Russian");
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
printf("Данная программа считывает ваш текст из файла, находит в нем три самых длинных и три самых коротких слова, а также располагает все слова в порядке, обратном алфавитному.nnn");
system("pause");
system("cls");
for (;;) {
load = fopen("FILE.txt", "r");
fscanf_s(load, "%in", &kolslov);
initialization(biggest, little);
b = new char*[kolslov];
/*for (int i = 0; i < kolslov; i++) {
b[i] = new char[30];
}*/
buffer = new char[300];
token = new char[300];
fgets(buffer, len_text, load);
printf("Первоначальный текст:nn%snnnНайденные слова:nn", buffer);
token = strtok(buffer, delims);
int i = 0;
while (token != NULL)
{
int len = strlen(token);
b[i] = new char[300];
b[i] = token;
Nslov++;
printf("%sn", b[i]);
i++;
bigswap(i, len, biggest);
littleswap(i, len, little);
token = strtok(NULL, delims);
}
printf("nnТри самых длинных слова в данном тексте:nn%sn%sn%snn", b[biggest[1]], b[biggest[3]], b[biggest[5]]);
printf("nТри самых коротких слова в данном тексте:nn%sn%sn%snnn", b[little[1]], b[little[3]], b[little[5]]);
minusswap(b, kolslov);
gettext(b, kolslov);
system("pause");
for (int i = 0; i < kolslov; i++) {
printf("n%sn", b[i]);
delete[] b[i];
}
delete[] b;
fclose(load);
system("pause");
system("cls");
}
system("pause");
}
Код того места, где появляется проблема, которая в дальнейшем вызывает ошибку:
while (token != NULL)
{
int len = strlen(token);
b[i] = new char[300];
b[i] = token;
Nslov++;
printf("%sn", b[i]);
i++;
bigswap(i, len, biggest);
littleswap(i, len, little);
token = strtok(NULL, delims);
}
Код, при прохождении которого появляется ошибка:
for (int i = 0; i < kolslov; i++) {
printf("n%sn", b[i]);
delete[] b[i];
}
delete[] b;
Ошибка: вызвано срабатывание точки останова в функции delete_scalar.cpp
//
// delete_scalar.cpp
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Defines the scalar operator delete.
//
#include <crtdbg.h>
#include <malloc.h>
#include <vcruntime_new.h>
void __CRTDECL operator delete(void* const block) noexcept
{
#ifdef _DEBUG
_free_dbg(block, _UNKNOWN_BLOCK);
#else
free(block);
#endif
}
Ошибка в строке: _free_dbg(block, _UNKNOWN_BLOCK);
Я изучил C ++ в онлайн-курсе, но у меня возникла проблема с оператором «delete» в Visual Studio. Когда удаление выполняется, он открывает файл delete_scalar.cpp
и показывает:
ConsoleApplication.exe вызвал точку останова. исключение
Я уже перемещаю папку SymbolCache из temp, включая wntdll.pdb и т. Д.
#include "pch.h"#include <iostream>
using namespace std;
int main()
{
int *pInt = new int;
*pInt = 3;
cout << *pInt << endl;
cout << pInt << endl;
delete[] pInt; //error -- UPDATED: still get error with `delete pInt;`
return 0;
}
здесь информация о выходе,
«ConsoleApplication11.exe» (Win32): загружен «C: Windows SysWOW64 ntdll.dll». Символы загружены.
«ConsoleApplication11.exe» (Win32): загружен «C: Windows SysWOW64 kernel32.dll». Символы загружены.
«ConsoleApplication11.exe» (Win32): загружен «C: Windows SysWOW64 KernelBase.dll». Символы загружены.
«ConsoleApplication11.exe» (Win32): загружен «C: Windows SysWOW64 msvcp140d.dll». Символы загружены.
«ConsoleApplication11.exe» (Win32): загружен «C: Windows SysWOW64 vcruntime140d.dll». Символы загружены.
«ConsoleApplication11.exe» (Win32): загружен «C: Windows SysWOW64 ucrtbased.dll». Символы загружены.
Поток 0x2fd0 вышел с кодом 0 (0x0).
HEAP [ConsoleApplication11.exe]: неверный адрес, указанный для RtlValidateHeap (00930000, 009359E8)
ConsoleApplication11.exe вызвал точку останова.
delete_scalar.cpp из самого визуала,
//
// delete_scalar.cpp
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Defines the scalar operator delete.
//
#include <crtdbg.h>
#include <malloc.h>
#include <vcruntime_new.h>
#include <vcstartup_internal.h>
_CRT_SECURITYCRITICAL_ATTRIBUTE
void __CRTDECL operator delete(void* const block) noexcept
{
#ifdef _DEBUG
_free_dbg(block, _UNKNOWN_BLOCK); // the circle X symbol showed up there
#else
free(block);
#endif
}
Я уже делаю точки останова, такие как включение и удаление, но точка останова все еще срабатывает на delete_scalar.cpp с отображением символа X круга.
0
Решение
Если вы попросите памяти с new
необходимо удалить с помощью delete
,
Использовать только delete [ ]
когда ты использовал new [ ]
, Несовпадение двух приводит к неопределенному поведению.
2
Другие решения
Других решений пока нет …
Я изучил C++ на онлайн-курсе, но у меня проблема с оператором delete в Visual Studio. Когда выполняется удаление, он открывает файл delete_scalar.cpp и показывает:
ConsoleApplication.exe has triggered a breakpoint. exception thrown
Я уже перемещаю папку SymbolCache из temp, включая wntdll.pdb и т. д.
#include "pch.h"
#include <iostream>
using namespace std;
int main()
{
int *pInt = new int;
*pInt = 3;
cout << *pInt << endl;
cout << pInt << endl;
delete[] pInt; //error -- UPDATED: still get error with `delete pInt;`
return 0;
}
Здесь выходная информация,
‘ConsoleApplication11.exe’ (Win32): Loaded ‘C:WindowsSysWOW64ntdll.dll’. Symbols loaded.
‘ConsoleApplication11.exe’ (Win32): Loaded ‘C:WindowsSysWOW64kernel32.dll’. Symbols loaded.
‘ConsoleApplication11.exe’ (Win32): Loaded ‘C:WindowsSysWOW64KernelBase.dll’. Symbols loaded.
‘ConsoleApplication11.exe’ (Win32): Loaded ‘C:WindowsSysWOW64msvcp140d.dll’. Symbols loaded.
‘ConsoleApplication11.exe’ (Win32): Loaded ‘C:WindowsSysWOW64vcruntime140d.dll’. Symbols loaded.
‘ConsoleApplication11.exe’ (Win32): Loaded ‘C:WindowsSysWOW64ucrtbased.dll’. Symbols loaded.
The thread 0x2fd0 has exited with code 0 (0x0).
HEAP[ConsoleApplication11.exe]: Invalid address specified to RtlValidateHeap( 00930000, 009359E8 )
ConsoleApplication11.exe has triggered a breakpoint.
Delete_scalar.cpp из самого визуала,
//
// delete_scalar.cpp
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Defines the scalar operator delete.
//
#include <crtdbg.h>
#include <malloc.h>
#include <vcruntime_new.h>
#include <vcstartup_internal.h>
_CRT_SECURITYCRITICAL_ATTRIBUTE
void __CRTDECL operator delete(void* const block) noexcept
{
#ifdef _DEBUG
_free_dbg(block, _UNKNOWN_BLOCK); // the circle X symbol showed up there
#else
free(block);
#endif
}
Я уже выполняю такие действия с точкой останова, как включение и удаление, но точка останова все еще срабатывает на delete_scalar.cpp с отображением символа X в виде круга.
- Remove From My Forums
-
Question
-
Greetings…
Anyone can advise what is wrong and what can be done?
CRunProcess* m_Proc[NUM_PROC]; CMainClass::~CMainClass() { for (int i = 0; i < NUM_PROC; i++) { if (m_Proc[i] != NULL) { delete m_Proc[i]; m_Proc[i] = NULL; } } } m_Proc[RUN_PROCESS_1] = new CProcess1(); virtual ~CProcess1() { // OK } m_Proc[RUN_PROCESS_2] = new CProcess2(); virtual ~CProcess2() { // OK } m_Proc[RUN_PROCESS_3] = new CProcess3(); virtual ~CProcess3() { // Here Have Nothing also encountered error during Program exit // NOT OK ; calling destructor Twice, failed on 2nd time // An unhandled exception was encountered during a user callback // Scalar deleting destructor } m_Proc[RUN_PROCESS_4] = new CProcess4(); virtual ~CProcess4() { // OK }
Thanks a bunch!
CHeers~~~
- Forum
- General C++ Programming
- Execption thrown when deleting a valid p
Execption thrown when deleting a valid pointer
Hi Fellow Programmers!
I am having some trouble with this small project.
I am getting a exception thrown at me from «delete_scalar.cpp:Line 34: _free_dbg(block, _UNKNOWN_BLOCK);»
Which stems from me trying to delete a pointer holding a char array.
Here is context
The Destructor
|
|
Here is the declarations of the objects
|
|
When the client code completes and the destructors start deleting the pointers, once the destructor hits mainMenu it throws the exception, the first four objects exit fine.
Here is the values right at return 0, before destructors get called.
|
|
It’s confusing me, weird error aswell oh and heres the error as seen from my eyes.
Debug Assertion Failed! Program: ....myFilesProject.exe File:minkernelcrtsucrtsrcappcrtheapdebug_heap.cpp Line: 904 Expression: _CrtIsValidHeapPointer(block)
P.S does memory management in c++ ever become second nature to you oldies asking from a starter in college
Last edited on
Good luck finding a programmer who can correct a memory problem without reading the source code.
There’s no evidence of any exception being thrown in what you posted.
Post a small, self-contained, compilable example of the problem:
http://www.sscce.org/
P.S does memory management in c++ ever become second nature to you oldies asking from a starter in college
It becomes natural when you stop writing
new
everywhere.
Last edited on
Show how you construct the objects. Show the places you call new and new[].
Also, setting a pointer to null in a destructor is probably useless because the object the pointer belongs to is about to not exist anyway.
Also also, your check on line 9 is redundant.
So is your check on line 3.
P.S does memory management in c++ ever become second nature to you oldies asking from a starter in college
If you don’t use new & delete, you don’t need to worry about «classic» memory management, although should always be conscious of what is happening in your code.
Last edited on
Here is the reproducable example, tried to keep it simple.
|
|
I have to keep it passed by value.
Here is the client code with values before and after being passed into the new scope
|
|
|
|
Here are the values before going in…
|
|
and after leaving scope back to client code….
|
|
mainMenu and subMenu1 both get deleted, but mainMenu is the one that crashes when being destructed, subMenu1 destructs before mainMenu…
Let’s reduce the problem more:
|
|
See:
http://coliru.stacked-crooked.com/a/b06d48900f33a4bd
After line 10, both
x.ptr_
and
y.ptr_
point to the same object.
Destruction occurs in reverse order of construction. When
main
returns,
y.~a
is called, deleting
y.ptr_
. Next,
x.~a
is called, deleting
x.ptr_
. Unfortunately,
x.ptr_
and
y.ptr_
have the same value. The source of the problem is the attempt to
delete
the same pointer twice.
In the above program, we copy x into y on line 10, and this is the source of the problem. The copy in your code is harder to spot, but it occurs on line 44.
To fix the problem, either
a.) disallow copies; or
b.) duplicate the resource.
Case a.) is the simplest option, but it isn’t always suitable. We add the definitions
|
|
to our code. Now we are forbidden to copy or assign tempMenu objects; attempts to do so will result in a compiler error, and not an error that results in wrong behavior on the user’s machine.
We can still pass tempMenu objects as function arguments by binding them to reference parameters:
|
|
Last edited on
How do we duplicate the resource, my module uses the functionality of
|
|
to assign menu’s to one another
Add the definitions
|
|
to
tempMenu
Look up the «copy-and-swap» idiom for more information about the copy assignment operator. The copy constructor is the more problematic of the two, but it should do for now.
Last edited on
Topic archived. No new replies allowed.
Я изучил C ++ на онлайн-курсе, но у меня проблема с оператором delete в Visual Studio. При выполнении удаления открывается файл delete_scalar.cpp
и отображается:
ConsoleApplication.exe вызвал точку останова. выброшенное исключение
Я уже перемещаю папку SymbolCache из temp, включая wntdll.pdb и т. Д.
#include "pch.h"
#include <iostream>
using namespace std;
int main()
{
int *pInt = new int;
*pInt = 3;
cout << *pInt << endl;
cout << pInt << endl;
delete[] pInt; //error -- UPDATED: still get error with `delete pInt;`
return 0;
}
Здесь выходная информация,
‘ConsoleApplication11.exe’ (Win32): загружен ‘C: Windows SysWOW64 ntdll.dll’. Символы загружены. ‘ConsoleApplication11.exe’ (Win32): загружен ‘C: Windows SysWOW64 kernel32.dll’. Символы загружены. ‘ConsoleApplication11.exe’ (Win32): загружен ‘C: Windows SysWOW64 KernelBase.dll’. Символы загружены. «ConsoleApplication11.exe» (Win32): загружен «C: Windows SysWOW64 msvcp140d.dll». Символы загружены. «ConsoleApplication11.exe» (Win32): загружен «C: Windows SysWOW64 vcruntime140d.dll». Символы загружены. «ConsoleApplication11.exe» (Win32): загружен «C: Windows SysWOW64 ucrtbased.dll». Символы загружены. Поток 0x2fd0 завершился с кодом 0 (0x0). HEAP [ConsoleApplication11.exe]: для RtlValidateHeap (00930000, 009359E8) указан недопустимый адрес. Программа ConsoleApplication11.exe вызвала точку останова.
Delete_scalar.cpp из самого визуала,
//
// delete_scalar.cpp
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Defines the scalar operator delete.
//
#include <crtdbg.h>
#include <malloc.h>
#include <vcruntime_new.h>
#include <vcstartup_internal.h>
_CRT_SECURITYCRITICAL_ATTRIBUTE
void __CRTDECL operator delete(void* const block) noexcept
{
#ifdef _DEBUG
_free_dbg(block, _UNKNOWN_BLOCK); // the circle X symbol showed up there
#else
free(block);
#endif
}
Я уже использую точки останова, такие как включение и удаление, но точка останова все еще срабатывает на delete_scalar.cpp с отображением символа X в виде круга.
1 ответ
Лучший ответ
Если вы запрашиваете память с помощью new
, вам необходимо удалить ее с помощью delete
.
Используйте delete [ ]
только тогда, когда вы использовали new [ ]
. Несоответствие этих двух параметров ведет к неопределенному поведению.
4
Aganju
30 Окт 2018 в 07:50