Here is my function that reads in a list of integers and doubles the size of the array if there are too many inputs. The current size of the array is 10.

int* read_list ( int *list, size_t *list_size_ptr, size_t *array_size ){
    
    size_t index = 0;
    int *new_list;
    
    while ( cin >> list[index] ){
       
	if ( index >= *array_size-1 ){
	    
	    *array_size *= 2;
	    new_list = new int[*array_size];
	    int new_size = (int)(*array_size/2)*sizeof(int);
	    memcpy ( new_list, list, new_size );
	    list = new_list;
	    delete [] new_list;
	       
	}
	index++;
    }
    
    *list_size_ptr = index;
    
    return list;   
}

This code works well for lists of size 8 or 16, but with sizes larger than 20 it outputs 0, 2, 0, 4, 0, 6, 0, 8, 9, 10, 11, ...

I'm just not sure why. I would think it would mess up like that the first time it reallocates a new size but it starts to do it the second time. Any ideas? Thanks.

Recommended Answers

All 6 Replies

Member Avatar for iamthwee

> any ideas?
Use a std::vector instead perhaps.

>This code works well for lists of size 8 or 16, but with sizes larger than 20 it outputs 0, 2, 0, 4, 0, 6, 0, 8, 9, 10, 11, ...
What was your expected output here ?

Use a std::vector instead perhaps.

I can't use vectors.

What was your expected output here ?

Sorry about that. It was supposed to be 1, 2, 3, 4, 5, ...

You should post a short, complete program, including the array display function, the read_list function, and the main function that calls both. Throw in some comments describing the variables and what they represent. There could well be a problem in calling or displaying the array rather than a problem with the function itself. throw in an input file too. We don't know what is stored in the arrays BEFORE the function is called otherwise. There's more than own way to write this function, using different parameters.

Look carefully at lines 14 and 15 and put some debugging statements in there. It's just dumb luck, probably, that the program isn't crashing and you're not getting a seg fault. Line 14 causes a memory leak. The location pointed to by list prior to line14 is lost when line 14 is executed and the memory allocated to that array is never released and is inaccessible after line 14. Consider carefully what you are deleting in line 15.

int* read_list ( int *list, size_t *list_size_ptr, size_t *array_size ){
    
    size_t index = 0;
    int *new_list;
    
    while ( cin >> list[index] ){
       
	if ( index >= *array_size-1 ){
	    
	    *array_size *= 2;
	    new_list = new int[*array_size];
	    int new_size = (int)(*array_size/2)*sizeof(int);
	    memcpy ( new_list, list, new_size );
	    list = new_list;
	    delete [] new_list;
	       
	}
	index++;
    }
    
    *list_size_ptr = index;
    
    return list;   
}

Ah ha, I think I got it.

I changed :

memcpy ( new_list, list, new_size );
list = new_list;
delete [] new_list;

to:

memcpy ( new_list, list, new_size );
delete [] list;
list = new_list;

because I want to first delete the memory allocated to list and then point it to new_list afterward. I figured that

delete [] list

would delete the actual pointer variable too, but apparently it just deletes its contents. Is that correct?

I figured that

delete [] list

would delete the actual pointer variable too, but apparently it just deletes its contents. Is that correct?

It releases the memory formerly reserved for the integers themselves. It does nothing to their contents, but it allows the computer to use that formerly reserved memory for something else. Below is a program and its results.

#include <iostream>
using namespace std;

int main ()
{
    int* a = new int[4];
    int* b = new int[4];
    
    a[0] = 1;
    b[0] = 2;
    
    cout << &a <<  " " << &a[0] << " " << &a[3] << " " << a[0] << endl;
    cout << &b <<  " " << &b[0] << " " << &b[3] << " " << b[0] << endl;

    delete []a;
    int* c = new int[4];
    c[0] = 3;
    
    cout << "After []a has been deleted.\n";
    cout << &a <<  " " << &a[0] << " " << &a[3] << " " << a[0] << endl;
    cout << &b <<  " " << &b[0] << " " << &b[3] << " " << b[0] << endl;
    cout << &c <<  " " << &c[0] << " " << &c[3] << " " << c[0] << endl;
    
    a = b;
    
    cout << "After a has been assigned to equal b.\n";
    cout << &a <<  " " << &a[0] << " " << &a[3] << " " << a[0] << endl;
    cout << &b <<  " " << &b[0] << " " << &b[3] << " " << b[0] << endl;
    cout << &c <<  " " << &c[0] << " " << &c[3] << " " << c[0] << endl;

    return 0;
}

Results:

0x22ff74 0x3e3bb0 0x3e3bbc 1
0x22ff70 0x3e3bc8 0x3e3bd4 2
After []a has been deleted.
0x22ff74 0x3e3bb0 0x3e3bbc 3
0x22ff70 0x3e3bc8 0x3e3bd4 2
0x22ff6c 0x3e3bb0 0x3e3bbc 3
After a has been assigned to equal b.
0x22ff74 0x3e3bc8 0x3e3bd4 2
0x22ff70 0x3e3bc8 0x3e3bd4 2
0x22ff6c 0x3e3bb0 0x3e3bbc 3

I'm using a 32 bit system. A byte is 8 bits, an int is 4 bytes, a 4 integer array is 16 bytes.

Line 6 ==> A pointer to an integer array is created at memory location 0x22ff74. 16 bytes of memory are reserved from 0x3e3bb0 through 0x3e3bbf for the 4 integers in the array. Memory location 0x22ff74 contains 0x3e3bb0, the address of the first element of the a[] array.

Line 7 ==> A pointer to an integer array is created at memory location 0x22ff70. 16 bytes of memory are reserved from 0x3e3bc8 through 0x3e3bd7 for the 4 integers in the array. Memory location 0x22ff70 contains 0x3e3bc8, the address of the first element of the b[] array.

Line 9 ==> Contents of 0x3e3bb0 is now 1.
Line 10 ==> Contents of 0x3e3bc8 is now 2.


Line 15 ==> Memory locations 0x3e3bb0 through 0x3e3bbf are "released", meaning the operating system is allowed to assign them in the next "new" command if it chooses to.

Line 16 ==> Request is made for 16 bytes. 0x3e3bb0 through 0x3e3bbf are available, so operating system assigns them to c[] array. Address 0x22ff6c has contents 0x3e3bb0, the first element of the c[] array. 0x22ff74 also still contains 0x3e3bb0 as well.

a and c now point to the same address.
a[0] and c[0] are both 1.

Line 17 ==> Contents of 0x3e3bb0 is now 3.
a[0] and c[0] are both 3.

Line 24 ==> 0x22ff74 is changed to 0x3e3bc8, the address of the first element of the b[] array.
a[0] and b[0] are now 2.

So you have two arrays' worth of storage, and three pointers to arrays. So to sum up, yes, the pointer is NOT deleted, but the memory pointed to by the pointer is RELEASED into the pool of memory available that the OS can assign however it sees fit. Hope this helps.

commented: Nice posting! Keep up the good work :) +16
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.