How to understand copy-constructior function?

75 views Asked by At
    #include<iostream>
    #include<stdio.h>
    #include<string.h>

    class String{

    public:
            String(){}
            String(const char *ptr)
            {
                    pstr_= new char[strlen(ptr) + 1];
                    strcpy(pstr_,ptr);
            }
            String(const String &str)
            {
                    strcpy(this->pstr_,str.get_pstr());
            }

            ~String()
            {
                    delete pstr_ ;
            }

            char *get_pstr()
            {
                    return pstr_ ;
            }
    private:
            char *pstr_ ;

    };

    int main(int argc,char *argv[])
    {
            char *sh = "Hello World";
            String str(sh) ;
            String st(str) ;
            std::cout << str.get_pstr() << std::endl ;

            return 0 ;
    }

Sorry,my English is bad and help you can understanding my meaning . I write a code like this . I'm sure that it is correct .However, it can produce segement fault . SO, I find a strange phenomenon by gdb .

38              std::cout << str.get_pstr() << std::endl ;
(gdb) n

Breakpoint 1, String::get_pstr (this=0x7fffffffe470) at String.cpp:26
26                      return pstr_ ;
(gdb) n
27              }
(gdb) n
Hello World
main (argc=1, argv=0x7fffffffe578) at String.cpp:40
40              return 0 ;
(gdb) n
37              String st(str) ;
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7282ba1 in __strlen_sse2 () from /lib64/libc.so.6

when the program is running to return 0 ,it can rerun String st(str). And i'm worried about it.Help you can explain it.Thank you !

2

There are 2 answers

2
UncleZeiv On

So, there are two issues here.

The crash is due to the fact that you are not allocating new memory in the copy constructor. Compare that to the normal constructor where you correctly do it before copying the string.

The second issue is that gdb is behaving in this case in a confusing way. You probably compiled your code with some level of optimization, such that the compiler is allowed to reorder instructions around. As the copy constructed string is not needed during the cout print, for some reason it was moved past it, and that's what gdb is showing you. Try recompiling your code without optimizations and you should see the instructions being executed in the order you wrote them in.

1
cybersoft On

You should allocate memory in copy constructor also:

String(const String &str)
{
    pstr_= new char[strlen(ptr.get_pstr()) + 1];
    strcpy(this->pstr_,str.get_pstr());
}

or:

String(const String &str): String(str.get_pstr()) { }