Resizing dynamic array of Class C++ -


i need resize m_array , saying problems in valgrind when adding 11. element m_max = 10 m_len = 10 allowed use cstdio,cstdlib,cstring , iostream.

/* m_len length of array , m_max maximal length */ resizing in caccount::newaccount  if ( m_len >= m_max ) {      if (m_max == 0) m_max = 5;      m_max *= 2;      caccount * tmp = new caccount[m_max];      memcpy ( tmp, m_array, m_len * sizeof(caccount));      delete[] m_array;      m_array = tmp;  } m_array[m_len] = x; m_len++; 

here aditional code involved in this:

caccount {  public:   ~caccount ( void )   {     delete[] m_trans;   } private:  struct transaction  {    int a;    const char * b;    const char * c;  } transaction * m_trans;   }   caccount * m_array; 

this valgrind says

my couts...

==2458== invalid read of size 4 ==2458==    @ 0x8048d67: caccount::addtransaction(int const&, char const*, char const*) (bank_test.cpp:121) ==2458==    0x8049645: cbank::transaction(char const*, char const*, int, char const*) (bank_test.cpp:268) ==2458==    0x8049946: main (bank_test.cpp:327) ==2458==  address 0x434b150 0 bytes inside block of size 4 free'd ==2458==    @ 0x402b598: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==2458==    0x8048b0a: caccount::~caccount() (bank_test.cpp:92) ==2458==    0x804951e: cbank::newaccount(char const*, int) (bank_test.cpp:254) ==2458==    0x804991b: main (bank_test.cpp:323) ==2458==  ==2458== invalid free() / delete / delete[] / realloc() ==2458==    @ 0x402b598: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==2458==    0x8048d9a: caccount::addtransaction(int const&, char const*, char const*) (bank_test.cpp:121) ==2458==    0x8049645: cbank::transaction(char const*, char const*, int, char const*) (bank_test.cpp:268) ==2458==    0x8049946: main (bank_test.cpp:327) ==2458==  address 0x434b150 0 bytes inside block of size 4 free'd ==2458==    @ 0x402b598: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==2458==    0x8048b0a: caccount::~caccount() (bank_test.cpp:92) ==2458==    0x804951e: cbank::newaccount(char const*, int) (bank_test.cpp:254) ==2458==    0x804991b: main (bank_test.cpp:323) ==2458==  ==2458== invalid read of size 4 ==2458==    @ 0x8048d67: caccount::addtransaction(int const&, char const*, char const*) (bank_test.cpp:121) ==2458==    0x8049678: cbank::transaction(char const*, char const*, int, char const*) (bank_test.cpp:269) ==2458==    0x8049946: main (bank_test.cpp:327) ==2458==  address 0x434b188 0 bytes inside block of size 4 free'd ==2458==    @ 0x402b598: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==2458==    0x8048b0a: caccount::~caccount() (bank_test.cpp:92) ==2458==    0x804951e: cbank::newaccount(char const*, int) (bank_test.cpp:254) ==2458==    0x804991b: main (bank_test.cpp:323) ==2458==  ==2458== invalid free() / delete / delete[] / realloc() ==2458==    @ 0x402b598: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==2458==    0x8048d9a: caccount::addtransaction(int const&, char const*, char const*) (bank_test.cpp:121) ==2458==    0x8049678: cbank::transaction(char const*, char const*, int, char const*) (bank_test.cpp:269) ==2458==    0x8049946: main (bank_test.cpp:327) ==2458==  address 0x434b188 0 bytes inside block of size 4 free'd ==2458==    @ 0x402b598: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==2458==    0x8048b0a: caccount::~caccount() (bank_test.cpp:92) ==2458==    0x804951e: cbank::newaccount(char const*, int) (bank_test.cpp:254) ==2458==    0x804991b: main (bank_test.cpp:323) ==2458==  

then writes couts , says this

==2458== invalid read of size 4 ==2458==    @ 0x8048ad7: caccount::~caccount() (bank_test.cpp:92) ==2458==    0x804922e: cbank::~cbank() (bank_test.cpp:224) ==2458==    0x80499f0: main (bank_test.cpp:381) ==2458==  address 0x434b348 0 bytes inside block of size 4 free'd ==2458==    @ 0x402b598: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==2458==    0x8048b0a: caccount::~caccount() (bank_test.cpp:92) ==2458==    0x804951e: cbank::newaccount(char const*, int) (bank_test.cpp:254) ==2458==    0x804991b: main (bank_test.cpp:323) ==2458==  ==2458== invalid free() / delete / delete[] / realloc() ==2458==    @ 0x402b598: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==2458==    0x8048b0a: caccount::~caccount() (bank_test.cpp:92) ==2458==    0x804922e: cbank::~cbank() (bank_test.cpp:224) ==2458==    0x80499f0: main (bank_test.cpp:381) ==2458==  address 0x434b348 0 bytes inside block of size 4 free'd ==2458==    @ 0x402b598: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==2458==    0x8048b0a: caccount::~caccount() (bank_test.cpp:92) ==2458==    0x804951e: cbank::newaccount(char const*, int) (bank_test.cpp:254) ==2458==    0x804991b: main (bank_test.cpp:323) ==2458==  ==2458==  ==2458== heap summary: ==2458==     in use @ exit: 0 bytes in 0 blocks ==2458==   total heap usage: 17 allocs, 27 frees, 1,268 bytes allocated ==2458==  ==2458== heap blocks freed -- no leaks possible ==2458==  ==2458== counts of detected , suppressed errors, rerun with: -v ==2458== error summary: 20 errors 6 contexts (suppressed: 0 0) 

this happens:

caccount * tmp = new caccount[m_max];

you created 20 new objects caccount.

memcpy ( tmp, m_array, m_len * sizeof(caccount));

you memcpy-ied content of 10 old objects caccount new array.

the problem is, used memcpy , no copy constructor take care of ownership of data, both new , old versions of objects pointing same m_trans data.

once call delete[] m_array; destructors on old objects called, , remove m_trans

delete[] m_trans;

now new objects pointing m_trans data removed accessing pointer lead undefined behavior.

the cleanest way solve use instead of

memcpy ( tmp, m_array, m_len * sizeof(caccount));

do

std::copy(m_array, m_array + m_len, tmp)

this calls opreator= on new objects, need make correctly well:

caccount { public:   caccount::caccount(const caccount& account)   : m_trans(<initialisation code here>) {   <copy data account> } 

this solution cleanest sub-optimal, copying data, switch owner of data, if not shooting performance better.


Comments

Popular posts from this blog

apache - Remove .php and add trailing slash in url using htaccess not loading css -

javascript - jQuery show full size image on click -