I'm writing a backtracking problem for homework, and all the code works except for my delete[] at the end.
/*Assg4.cc*/
int main()
{
//removed irrelevant code - see pastebin links if needed
void *data = &datavector;
bool finished = false;
bool* continuance = &finished;
int *a = new int[n+1];
for(int i=0; i<n; i++)
{
a[i] = NULL;
}
delete []a;
delete continuance;
return 0;
}
I get the following error:
*** glibc detected *** ./Assg4: free(): invalid pointer: 0xbfc7098f ***
The function backtrack() merely fills the contents of the array a[] at some point, it doesn't delete, expand, or shrink the array in any way. I know the problem is with the deletes at the end, because when I comment them out I get no error (and the result of all computations is correct). What am I doing wrong?
Pastebin full files:
Assg4.cc
backtrack.cc & backtrack.h
Pretty sure your error is actually here:
delete continuance;
You're trying to delete something allocated on the stack, since continuance points to finished, which is allocated on the stack (without a call to new). Items on the stack will be destroyed automatically when they go out of scope, so you don't have to worry about deleting continuance.
See: What and where are the stack and heap
bool finished = false;
bool* continuance = &finished;
delete continuance;
You are calling delete on a pointer which is not allocated using new. This is causing an Undefined Behavior.
finished is a automatic/local variable which is autmatically destroyed once the scope { } in which it is declared ends.
The rule is simple:
Don't call delete unless you called new.
Related
I'm writing my first opencv code(and first C++ code actually), and met with a strange munmap_chunk(): invalid pointer error when I try to use cv::Ptr. I see in other posts that this usually results from freeing a already freed area, but I think I didn't.
The following simple testing function will generate that error.
void testing(void) {
int i=2;
Ptr< Mat > pointer=new Mat[i];
}
From the debugger, it seems that the destructor triggers the error when the function returns.I couldn't figure out why since basically I did nothing with the Ptr. So why this is happening and what's the correct usage?
Thanks in advance.
In C++ there is a significant difference between memory allocated with new and memory allocated with new [].
int* p = new int;
delete p;
p = new int[8];
delete p; // error/crash
delete [] p; // correct
The Ptr class is an RAII container for managing ownership of pointers. When you assign to it, it takes ownership of that allocation, meaning it will delete it when the Ptr goes out of scope (in this case at the end of the function).
It uses delete by default hence your crash, and the documentation suggests you will need to use the constructor that lets you specify you own deleter:
// see http://docs.opencv.org/master/d0/de7/structcv_1_1Ptr.html
void array_deleter(Mat* m)
{
delete [] m;
}
Prt<Mat> ptr(new Mat[i], array_deleter);
Here is my function:
void Tetris::place_square(int* coords,char type){
if (coords[1]>heights[coords[0]]){
char* old=data[coords[0]];
data[coords[0]]=new char[coords[1]];
for (unsigned int i=0; i<heights[coords[0]]; ++i){
data[coords[0]][i]=old[i];
}
for (unsigned int i=heights[coords[0]]; i<coords[1]; ++i){
data[coords[0]][i]=" "[0];
}
data[coords[0]][coords[1]-1]=type;
heights[coords[0]]=coords[1];
delete old;
} else {
data[coords[0]][coords[1]-1]=type;
}
}
It compiles fine but when I try to run it i get malloc: *** error for object 0x7fff503e0020: pointer being freed was not allocated
I believe the problem is delete old; but I don't know how to fix it.
Looking at this section:
char* old=data[coords[0]];
data[coords[0]]=new char[coords[1]];
I'm not sure what is in your data array, but it looks like you are assigning a pointer which has not yet been initialized.
If you are initializing with
data[i]=new char[0];
Then you should also be deleting with delete[].
The address indicates that data[coords[0]] was previously pointing to an automatic variable. You can only use delete on things that were allocated by new.
Also, you should use delete[] when things were allocated by new[] as they are in this example.
To fix this you will need to review the initialization of data and any code that might update data[x] . It is also possible that coords[0] is out of bounds for data.
I have a Trie program written in C++. There is an issue with deleting Trie. Even though the code is performing delete operation memory is not getting freed. Can someone point where I am doing wrong? Program doesn't deal with the individual string deletion from Trie. Below is the delete snippet of code.
void deleteTrie(trieNodeT **t) {
if(*t) {
trieNodeT *current = *t;
for(int i=0; i<26; i++) {
if(current->children[i]) {
deleteTrie(¤t->children[i]);
free (current->children[i]);
}
}
}
}
void deleteEntireTrie(trieCDT *t) {
if (t) {
deleteTrie(&t->root);
}
}
Below is the link of entire source code:
https://ideone.com/xL7bvu
Given that this is C++:
(trieNodeT *) malloc(sizeof(trieNodeT));
should be:
new trieNodeT;
You can't use delete and malloc together, it's undefined behavior.
Alternatively, you could replace:
delete current->children[i];
with
free(current->children[i]);
You also probably need to write out null into what you're deleting:
if(current->children[i]) {
deleteTrie(¤t->children[i]);
delete current->children[i];
current->children[i] = nullptr; // or 0
}
Where is the delete for the root node?
You do not need to null the pointer for deletion to take effect. The memory is 'marked' deleted with delete statement. If you do not null the pointer, then the pointer still points to the 'marked' deleted memory area. C++ purists would jump up and say that what I say following is wrong - immediately after a delete, if you access the memory through that old pointer, in many implementations, the data would still be there. Because the memory block was just marked as deleted; NOT physically overwritten. BUT you should never access that deleted memory. The program takes away that marked deleted memory and assigns it away when it next needs memory; and you do not have any control over it. And with multithreading, that memory might be gone even 'immediately'.
Tutorials, searches, and the dim memory of my C++ formal education have left me clueless as to where I should use delete when I'm using a dynamically allocated object pointer in a loop, such as:
// necessary files are included, this code is within main
T * t;
t = foo.getNewT();
while (!t->isFinalT()) {
// print t stuff
delete t; // is this where I should delete t?
t = foo.getNewT();
}
delete t;
This lack of knowledge has become particularly troublesome on a recent class project. On my laptop (Linux Mint, g++ Ubuntu/Linaro 4.7.3-1ubuntu1) the code ran fine without the delete statement and crashed when I added the delete statement. On the school server (Solaris, g++ (GCC) 3.4.5), the code segfaulted after a few iterations without the delete statement, and runs fine when I add the delete statement.
How do I handle this kind of loop properly so that it will run in most environments?
Additional Info:
The error on my laptop occurs when the program reaches the delete request:
*** Error in 'program': free(): invalid next size (fast):...
Some of the other code:
// T.h
class T {
int id;
int num;
int strVarPos;
char * strVar;
public:
T();
~T();
// + misc. methods
}
// T.cpp
T::T() {
id = 0;
num = -1;
strVarPos = 0;
char * strVar = new char[11];
strVar[0] = '\0'
}
T::~T() {
delete [] strVar;
}
// Foo.cpp
T * Foo::getNewT() {
T * t = new T;
// populate T's fields
return t;
}
Resolution:
Because a simple test with just T * t and the loop worked ok, I ended up reconstructing the project starting from blank and adding one class at a time, to see when the problem would appear. Turns out that I had added additional content into a dynamically allocated array elsewhere in the program without updating the size constant I was using to initialize the array.
Evidently the school server could only handle the resulting memory discrepancy without crashing if I was making sure to delete the pointers properly (the program didn't run long enough to cause a significant memory leak in my tests), while my laptop wouldn't notice the memory discrepancy until I attempted to call delete (and then would crash).
Assuming that foo.getNewT() is handing ownership of the memory over to the caller:
T * t;
t = foo.getNewT();
//while (!t->isFinalT()) // if foo.getNewT ever returns NULL, this will be UB!!!
while (t != nullptr && !t->isFinalT())
{
// ...
delete t; // if you now own it and are no longer going to use it, yes, delete it here
t = foo.getNewT();
}
delete t; // you also need this one to delete the "final" t
However, you can avoid having to do it yourself by using std::unique_ptr:
std::unique_ptr<T> t;
t.reset(foo.getNewT());
while (t && !t->isFinalT())
{
// ...
t.reset(foo.getNewT());
}
Alternatively, you could rewrite the loop to flow a bit better:
std::unique_ptr<T> t;
do
{
t.reset(foo.getNewT());
if (t)
{
// do stuff with t
}
} while (t && !t->isFinalT());
the code ran fine without the delete statement and crashed when I
added the delete statement.
Are you sure getNewT is handing ownership of the T* to you? If you delete it, and then it tries to delete it later, you will end up with a heap corruption. If it is handing ownership over to the caller, and you do not delete it, you get a memory leak.
With the additional information in your edit:
char * strVar = new char[11];
That line is unnecessary if you declare strVar as either a std::string or a char[11]. If you attempt to copy any of those T objects, you'll be using the default copy constructor (as you have not defined one), which will do a shallow copy (that is, copy the value of the pointer for strVar). When you delete 2 Ts that are both pointing to the same memory location, you get a heap corruption. The most robust solution would be to declare strVar as a std::string.
The problem is not the delete. You have put it in the right place. It's more likely something else you are doing that is causing undefined behaviour.
Note that you should have a delete t after the loop as well (to catch the last one). This is assuming that foo.getNewT() always returns a valid pointer (which it must, because you never check if it is NULL).
You should delete a dynamically allocated memory when you no longer need it. If you want t to hold its value inside the for loop, then delete it outside the loop otherwise delete it inside.
However, the best thing to do is to use std::unique_ptr when you really have to use pointers . It will take care of deallocating the memory itself when all references to the memory are destroyed. You should try to avoid allocating memory as much as you can. Use STL containers if they fit the job.
I think when you delete t you are deleting the real object inside your structure.
Maybe that what is causing the problem.
I am trying to delete memory allocation using a function.. The code is as follow...
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
using namespace std;
int NOS, *NO, *SQR;
int Square()
{
SQR = new int [NOS];
if (!SQR)
{
cout<<"Mem Error SQR \n";
exit(0);
}
for ( int i = 0; i < NOS; i++ )
{
SQR[i] = NO[i]*NO[i];
}
}
void ERASE_MEM()
{
if (SQR) delete [] SQR;
cout<<"Deleted 1\n";
if (NO != NULL) delete [] NO;
cout<<"Deleted 2\n";
}
int main ()
{
cout<<"Enter No : ";
cin >> NOS;
NO = new int [NOS];
if (!NO)
{
cout<<"Mem Error NO \n";
exit(0);
}
for ( int i = 0; i < NOS; i++ )
{
NO[i] = 1+i;
}
Square();
delete NO;
ERASE_MEM();
}
If the number is less than 15, the program works fine but if the NOS is greater than 15, I get the following error:
* glibc detected ./MEM: double free or corruption (top): 0x097fa008 **
I am doing this in order to create one function for all the memory de-allocations, that I can call while allocating memory. If allocation fails, this function will de-allocate all previous allocations.
Thanks
You are deleting NO twice, once in main and once inside ERASE_MEM. Also, the syntax of delete used in main is wrong, since its an array you should use delete[] (or better remove the statement). BTW, one more thing to note is that when new fails it doesn't return a NULL pointer instead it throws std::bad_alloc exception. So there is no point validating the memory location retunred from new. Also, do not use all capital letters for a function name, the general coding practice is to use the all caps name for macros only. It is also not necessary to check for NULL pointer before calling delete[]. Standard guarantees that deleting a NULL pointer will not do anything.
You delete NO (incorrectly) in the main code and then again (correctly) in ERASE_MEM
edit: calling delete doesn't set pointer to null, it can't do this since the call only gets the value of the pointer, not the pointer itself.
This is a little clearer with the 'C' version free(pData) can't change pData - only what pData points to. A common 'C' idiom is to define your own Free(void **ptr) which you call with Free(&pData) which can then set pData to NULL.
Also note that it's perfectly safe to call free / delete with a null pointer, the function does the check for you.
Don't feel too bad delete and delete [] are a nasty corner of C++, they are function calls that look like statements, and the [] syntax to delete and array is even worse. The only good part is that with smart pointers and modern C++ you never have to use them