delete [] var_name; //sometimes does not work

V

valerij

Please help. I have been on this problem for a week now.
I am using Windows 98SE, Microsoft Visual C++ 6.0
The following program only works when the function is not
called, BUT the function does EXACTLY what is in the
main() function. I am completely at a loss.

//==============code
#include <iostream.h>
#include <stdlib.h>

int fill_a(__int64 *list) {
int n, i;
n=8;
delete [] list;
list = new __int64 [n];
for (i=0;i<n;i++) {
list=5;
}
return n;
}

int main() {
__int64 *list;
char buffer[20];
int n, i;
list = new __int64;

//n = fill_a(list);

n=8;
delete [] list;
list = new __int64 [n];
for (i=0;i<n;i++) {
list=5;
}

for (i=0;i<n;i++) {
_i64toa(list, buffer, 10);
cout << buffer << endl;
}
delete [] list;
return 0;
}
//==============end of code

When:

n = fill_a(list);

/*n=8;
delete [] list;
list = new __int64 [n];
for (i=0;i<n;i++) {
list=5;
}*/

An error arises:

============================================================
Microsoft Visual C++ Debug Library

Program: ...ES\MICROSOFT VISUAL
STUDIO\MYPROJECTS\TEST13\DEBUG\TEST13.EXE
File: dbgdel.cpp
Line: 47

Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

For information on how your program can use assertion
failure, see the Visual C++ documentation on asserts.

(Press Retry to debug the application)

[Abort] [Retry] [Ignore]
============================================================

Thank you,
Valerij
 
J

Jim Langston

valerij said:
Please help. I have been on this problem for a week now.
I am using Windows 98SE, Microsoft Visual C++ 6.0
The following program only works when the function is not
called, BUT the function does EXACTLY what is in the
main() function. I am completely at a loss.

//==============code
#include <iostream.h>
#include <stdlib.h>

int fill_a(__int64 *list) {

This is accepting a pointer value. The address the pointer is pointing to
is copied into the local variable list
int n, i;
n=8;
delete [] list;

Okay, you deleted the memory that list was pointing to
list = new __int64 [n];

Note: this only changed the local pointer, list is a local variable. The
pointer inside main is unchanged
for (i=0;i<n;i++) {
list=5;
}
return n;
}

int main() {
__int64 *list;
char buffer[20];
int n, i;
list = new __int64;


list points to some memory here
//n = fill_a(list);

fill_a(list) deletes the memory that list was pointing to, but the list
local to main remains unchanged, it still points to the memory that is now
freed
n=8;
delete [] list;
list = new __int64 [n];
for (i=0;i<n;i++) {
list=5;
}

for (i=0;i<n;i++) {
_i64toa(list, buffer, 10);


And here you are trying to access memory that has already been freed.
cout << buffer << endl;
}
delete [] list;
return 0;
}
//==============end of code

When:

n = fill_a(list);

/*n=8;
delete [] list;
list = new __int64 [n];
for (i=0;i<n;i++) {
list=5;
}*/

An error arises:

<snip>

The solution to this is to pass a pointer to a pointer to the function, then
the function can change the actual pointer itself.

int fill_a(__int64** list) {
// ...
delete [] *list;
*list = new __int64 [n];
// ...
 
J

Jakob Bieling

Jim said:
int fill_a(__int64 *list) {
int n, i;
n=8;
delete [] list;
Okay, you deleted the memory that list was pointing to
list = new __int64 [n];
for (i=0;i<n;i++) {
list=5;
}
return n;
}
int main() {
__int64 *list;
char buffer[20];
int n, i;
list = new __int64;

list points to some memory here
fill_a(list) deletes the memory that list was pointing to, but the
list local to main remains unchanged, it still points to the memory
that is now freed

Careful tho: the 'list' pointer was allocated with 'new' but 'fill_a'
will try to free the memory with 'delete[]'. This is a No-No! Always use
'delete[]' if you got the memory from 'new[]' and always use 'delete' if you
got the memory from 'new'!

regards
 
S

Salt_Peter

valerij said:
Please help. I have been on this problem for a week now.
I am using Windows 98SE, Microsoft Visual C++ 6.0
The following program only works when the function is not
called, BUT the function does EXACTLY what is in the
main() function. I am completely at a loss.

//==============code
#include <iostream.h>
#include <stdlib.h>

int fill_a(__int64 *list) {
int n, i;
n=8;
delete [] list;
list = new __int64 [n];
for (i=0;i<n;i++) {
list=5;
}
return n;
}

int main() {
__int64 *list;
char buffer[20];
int n, i;
list = new __int64;

//n = fill_a(list);

n=8;
delete [] list;


You shouldn't reuse that pointer, nothing forces the compiler/platform
to release the allocation at this point.
list = new __int64 [n];

__int64 *p_list = new __int64 [n];
for (i=0;i<n;i++) {
list=5;
}

for (i=0;i<n;i++) {
_i64toa(list, buffer, 10);
cout << buffer << endl;
}
delete [] list;
return 0;
}
//==============end of code

When:

n = fill_a(list);


As already explained, the list pointer above is copied into a local.
/*n=8;
delete [] list;
list = new __int64 [n];
for (i=0;i<n;i++) {
list=5;
}*/

An error arises:

============================================================
Microsoft Visual C++ Debug Library

Program: ...ES\MICROSOFT VISUAL
STUDIO\MYPROJECTS\TEST13\DEBUG\TEST13.EXE
File: dbgdel.cpp
Line: 47

Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

For information on how your program can use assertion
failure, see the Visual C++ documentation on asserts.

(Press Retry to debug the application)

[Abort] [Retry] [Ignore]
============================================================

Thank you,
Valerij


Instead of using primitive arrays why not use std::vector instead.
If you really must use arrays and to bypass having to use dumb
pointers:

#include <iostream>
#include <ostream>
#include <algorithm>
#include <iterator>
#include <stdexcept>

template< typename T, const std::size_t Size >
class Array
{
T array[Size];
public:
Array() { }
Array(const Array& copy)
{
std::copy( copy.array,
copy.array + Size + 1,
array );
}
T& at(std::size_t idx)
{
if(idx < 0 || idx > Size)
throw std::range_error("array out of range");
return array[idx];
}
void fill(const T& t)
{
std::fill( array,
array + Size + 1,
t );
}
friend std::eek:stream&
operator<<(std::eek:stream& os, const Array& r_a)
{
std::copy( r_a.array,
r_a.array + Size - 1,
std::eek:stream_iterator< T >(os, ", ") );
return os << r_a.array[Size] << std::endl;
}
};

int main()
{
Array< double, 5 > darray;
darray.fill( 11.1 );
std::cout << darray;
try {
// double d = darray.at(6); // throws
double d = darray.at(5);
std::cout << d << std::endl;

} catch (const std::exception& r_e)
{
std::cerr << "Error: " << r_e.what();
std::cerr << std::endl;
}
}

/*
11.1, 11.1, 11.1, 11.1, 11.1
11.1, 11.1, 11.1, 11.1, 11.1
*/
 
V

valerij

I have worked on it a bit longer, and came up with the following. In
Microsoft Visual C++ 6 it works:

//code
#include <iostream.h>
#include <stdlib.h>

void fill_a(__int64** list, int n) {
delete [] list[0];
list[0]= new __int64 [n];
for (int i=0;i<n;i++) {
list[0]=i;
}
}

int main() {
__int64** ptr_list;
__int64 *list;
char buffer[20];
int n=20, i;
list = new __int66];
ptr_list=&list;
fill_a(ptr_list, n);
for (i=0;i<n;i++ ) {
_i64toa(list, buffer, 10);
cout << buffer << endl;
}
delete [] list;
return 0;
}
//end of code
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,996
Messages
2,570,238
Members
46,826
Latest member
robinsontor

Latest Threads

Top