c++ - Invalid free() / delete / delete[] / realloc() error in assignment operator -


i new programming , when trying run program using valgrind getting error this. googled hours solve problem. please can tell me going wrong. hope there mistake near assignment operator.

error:

==5130== invalid read of size 8 ==5130==    @ 0x400cfd: std::passwd::~passwd() (passwd.c++:18) ==5130==    0x400c06: main (p1.c++:21) ==5130==  address 0x5a1c040 0 bytes inside block of size 8 free'd ==5130==    @ 0x4c2bdec: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==5130==    0x400d16: std::passwd::~passwd() (passwd.c++:19) ==5130==    0x400bfa: main (p1.c++:17) ==5130==  ==5130== invalid free() / delete / delete[] / realloc() ==5130==    @ 0x4c2bdec: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==5130==    0x400d07: std::passwd::~passwd() (passwd.c++:18) ==5130==    0x400c06: main (p1.c++:21) ==5130==  address 0x5a1c420 0 bytes inside block of size 8 free'd ==5130==    @ 0x4c2bdec: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==5130==    0x400d07: std::passwd::~passwd() (passwd.c++:18) ==5130==    0x400bfa: main (p1.c++:17) ==5130==  ==5130== invalid free() / delete / delete[] / realloc() ==5130==    @ 0x4c2bdec: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==5130==    0x400d16: std::passwd::~passwd() (passwd.c++:19) ==5130==    0x400c06: main (p1.c++:21) ==5130==  address 0x5a1c040 0 bytes inside block of size 8 free'd ==5130==    @ 0x4c2bdec: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==5130==    0x400d16: std::passwd::~passwd() (passwd.c++:19) ==5130==    0x400bfa: main (p1.c++:17) ==5130==  ==5130==  ==5130== heap summary: ==5130==     in use @ exit: 120 bytes in 1 blocks ==5130==   total heap usage: 7 allocs, 8 frees, 729 bytes allocated ==5130==  ==5130== searching pointers 1 not-freed blocks ==5130== checked 192,896 bytes ==5130==  ==5130== 120 bytes in 1 blocks still reachable in loss record 1 of 1 ==5130==    @ 0x4c2ab80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==5130==    0x53c0024: getdelim (iogetdelim.c:66) ==5130==    0x5444b52: getpass (getpass.c:97) ==5130==    0x400f84: std::passwd::get() (passwd.c++:66) ==5130==    0x400b3c: main (p1.c++:9) ==5130==  ==5130== leak summary: ==5130==    lost: 0 bytes in 0 blocks ==5130==    indirectly lost: 0 bytes in 0 blocks ==5130==      possibly lost: 0 bytes in 0 blocks ==5130==    still reachable: 120 bytes in 1 blocks ==5130==         suppressed: 0 bytes in 0 blocks ==5130==  ==5130== error summary: 3 errors 3 contexts (suppressed: 0 0) ==5130==  ==5130== 1 errors in context 1 of 3: ==5130== invalid free() / delete / delete[] / realloc() ==5130==    @ 0x4c2bdec: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==5130==    0x400d16: std::passwd::~passwd() (passwd.c++:19) ==5130==    0x400c06: main (p1.c++:21) ==5130==  address 0x5a1c040 0 bytes inside block of size 8 free'd ==5130==    @ 0x4c2bdec: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==5130==    0x400d16: std::passwd::~passwd() (passwd.c++:19) ==5130==    0x400bfa: main (p1.c++:17) ==5130==  ==5130==  ==5130== 1 errors in context 2 of 3: ==5130== invalid free() / delete / delete[] / realloc() ==5130==    @ 0x4c2bdec: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==5130==    0x400d07: std::passwd::~passwd() (passwd.c++:18) ==5130==    0x400c06: main (p1.c++:21) ==5130==  address 0x5a1c420 0 bytes inside block of size 8 free'd ==5130==    @ 0x4c2bdec: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==5130==    0x400d07: std::passwd::~passwd() (passwd.c++:18) ==5130==    0x400bfa: main (p1.c++:17) ==5130==  ==5130==  ==5130== 1 errors in context 3 of 3: ==5130== invalid read of size 8 ==5130==    @ 0x400cfd: std::passwd::~passwd() (passwd.c++:18) ==5130==    0x400c06: main (p1.c++:21) ==5130==  address 0x5a1c040 0 bytes inside block of size 8 free'd ==5130==    @ 0x4c2bdec: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==5130==    0x400d16: std::passwd::~passwd() (passwd.c++:19) ==5130==    0x400bfa: main (p1.c++:17) ==5130==  ==5130== error summary: 3 errors 3 contexts (suppressed: 0 0) 

here header file passwd.h

#include<stdio.h> #include<iostream> #ifndef min_passwd_len #define min_passwd_len 6 #endif #ifndef max_passwd_len #define max_passwd_len 20 #endif #ifndef no_of_numbers #define no_of_numbers 1 #endif #ifndef no_of_alphabets #define no_of_alphabets 1 #endif #ifndef no_of_symbols #define no_of_symbols 1 #endif namespace std{   class passwd{    char **pwd;   public:    passwd& operator=(const passwd);    passwd();    ~passwd();    bool check_validity();    void tochar(char **);    void get();  }; } 

functions above header file: passwd.c++

#include<iostream> #include"passwd.h" #include<string.h> #include<unistd.h> #include<stdlib.h>  using namespace std;  passwd::passwd() {   pwd=(char **)malloc(sizeof(char*));   pwd[0]=(char *)malloc(9);   strcpy(pwd[0],"password"); }  passwd::~passwd() {    free(pwd[0]);    free(pwd); }  passwd& passwd::operator=(const passwd pswd) {   pwd[0]=(char *)realloc(pwd[0],strlen(*pswd.pwd)+1);   strcpy(pwd[0],*pswd.pwd);   return *this; }  bool passwd::check_validity() {   if(strlen(pwd[0])<=max_passwd_len&&strlen(pwd[0])>=min_passwd_len);   else     return false;     int number_count=0,alphabet_count=0,symbol_count=0;     for(int i=0;i<strlen(pwd[0]);i++)      {         if(pwd[0][i]<='9'&&pwd[0][i]>='0')          {             number_count++;          }         else if((pwd[0][i]>='a'&&pwd[0][i]<='z')||(pwd[0][i]>='a'&&pwd[0][i]<='z'))           {             alphabet_count++;            }         else if(pwd[0][i]>32&&pwd[0][i]!=127)           {             symbol_count++;           }       } if(number_count>=no_of_numbers&&alphabet_count>=no_of_alphabets  && symbol_count>=no_of_symbols)       return true;     else       return false; }  void passwd::tochar(char **pswd) {   *pswd=(char*)malloc(strlen(pwd[0])+1);   strcpy(*pswd,pwd[0]); }  void passwd::get() {   char *pswd;   pswd=getpass("");   pwd[0]=(char *)realloc(pwd[0],strlen(pswd)+1);   strcpy(pwd[0],pswd); } 

main program: p1.c++

#include"passwd.h" #include<iostream> #include<stdlib.h>  int main() {   using namespace std;   passwd p;   cout<<"enter password: ";   p.get();   if(p.check_validity())     cout<<"valid pwd.\n";   else     cout<<"invalid pwd.\n";   char *s;   p.tochar(&s);   cout<<s<<endl;   passwd x=p;   free(s);   x.tochar(&s);   cout<<s<<endl;   free(s); } 

your passwd class has implicitly defined copy constructor. if don't explicitly create constructor looks bit like

passwd(const passwd &other) 

then compiler automatically generate 1 copies members. when do

passwd x=p; 

then x.pwd = p.pwd;. result, when second passwd gets destructed, free pwd[0] , pwd second time.

to solve this, explicitly define copy constructor want (probably allocate new pwd , pwd[0] copy password it). or, alternately, define private copy constructor prevent being used. or if you're using modern constructor can explicitly delete copy constructor passwd(const passwd &other) = delete; in class declaration. note latter 2 options make passwd x = p; error.

this breaks if passwd x; x = p; due issue: operator= not take reference original, , copy made when invoking it. 1 define operator=(const passwd &pswd) - leaving out & copy of argument must made, done using copy constructor, causes double-free after return operator= , copied pswd destroyed.


Comments

Popular posts from this blog

powershell Start-Process exit code -1073741502 when used with Credential from a windows service environment -

twig - Using Twigbridge in a Laravel 5.1 Package -

c# - LINQ join Entities from HashSet's, Join vs Dictionary vs HashSet performance -