-2

Here's a code i wrote, the sm_string(like std::string) class:

class sm_string
{
....
    void _Add(sm_string a)
    {// it adds the string to string(concatenates) and saves result in (*this)
        printf("\n_Add %s %s\n",str,a());
        str = (char*)ReallocSave(str,Len()+a.Len()+1,Len()+1);
        memcpy(str+Len(),a(),a.Len()+1);
    }
    sm_string Add(sm_string a)
    {// it concatenates too, return result,doesnt change (*this)
        printf("\nAdd %s %s\n",str,a());
        sm_string res(str);
        res._Add(a);
        return res;
    }


    sm_string(char* a)      
    {// creates string from char* string
        str = (char*)malloc(strlen(a)+1);
        memcpy(str,a,strlen(a)+1);
        printf("Creating %s\n",str);
    }
    sm_string(int a)        
    {// creates string from int
        char buf[100];
        itoa(a,buf,10);
        str = (char*)malloc(strlen(buf)+1);
        memcpy(str,buf,strlen(buf)+1);
        printf("Creating %s\n",str);
    }
    sm_string()     
    {//creates null string {'\0'}

        str = (char*)malloc(1);
        str[0] = '\0';
        printf("Creating %s\n",str);
    }
    ~sm_string()
    {//frees the pointer
        printf("\nFree of %s\n",str);
        free(str);
    }
.....
};

That's the my realloc function(cause normal realloc may lose the content while allocating more memory)

void* ReallocSave(void* pointer,int size,int oldsize)
{//realloc, which doesnt loose the memory
    void* _instance = malloc(size);
    memcpy(_instance,pointer,min(size,oldsize));
    free(pointer);
    return _instance;
}

It's the main function:

...
sm_string a("1");
a._Add(a.Add(3));
printf("%s",a());
...

And when i run this i receive an error

https://i.stack.imgur.com/1IOCn.png

As you see the destructor of "113" - it's the string from main function - is called twice. At all there's 3 constructors calls and 4 destructors, how can i fix this?

Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
  • 4
    I don't believe that "normal realloc may lose the content while allocating more memory" is true. – unwind Apr 08 '15 at 12:50
  • 6
    Why are you using `malloc`, `free`, `memcpy`, and `char*` in C++? – Cory Kramer Apr 08 '15 at 12:51
  • Use const reference to pass parameters, use const char * to pass string literals – nogard Apr 08 '15 at 12:52
  • 1
    Where is your copy constructor and `operator=()` ? – Bill Lynch Apr 08 '15 at 12:52
  • And are we just supposed to close this as a duplicate of http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three? – Bill Lynch Apr 08 '15 at 12:53
  • I dont think this is an error, but just the deletion of the temporary `res` in your `Add` – 463035818_is_not_an_ai Apr 08 '15 at 12:53
  • 1
    -1 as you have failed to post code sufficient to reproduce. I don't see your `operator()` which you call. The `...` is a red flag: learn hoe to post a minimal, complete example. If you do not know ehat is going wrong, how can you know what to omit? Easy: omit it, **then test that omitting it kept the same problem alive**. Repeat until the code is short and describes your problem. It should work 100% until the error you do not understand occurs. – Yakk - Adam Nevraumont Apr 08 '15 at 13:04

1 Answers1

1

Just a guess:

Your parameter is a string, not a reference or a pointer of string but a string. Basically when _Add is called a copy of sm_string a is created on the stack.

The destructor is then called twice on the a the variable a in the _Add function (which is a copy of the original object) and on the a in your main function.

void _Add(sm_string a) <= Try to change a with a pointer or a reference
{
    // it adds the string to string(concatenates) and saves result in (*this)
    printf("\n_Add %s %s\n",str,a());
    str = (char*)ReallocSave(str,Len()+a.Len()+1,Len()+1);
    memcpy(str+Len(),a(),a.Len()+1);
}
Phong
  • 6,600
  • 4
  • 32
  • 61
  • This might work, but it's really just working around the real bug: the missing copy constructor and assignment operator. – Henrik Apr 08 '15 at 14:08