类析构函数更改程序结果

时间:2019-12-26 13:42:38

标签: c++

如果我注释析构函数,并且下面的代码显示“ Hello world”,则下面的代码正常工作 如果没有评论,它只打印“你好”! 注意我在Windows XP 32bits上使用mingw 4.9 和tha机是非常古老的Pintume 4 1.8ghz

奇怪的是,此代码可以在其他现代PC上正常运行,我只会在这台旧PC上收到此错误

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct String{
public:
    String(const char * txt){
        len = strlen(txt);
        if (len > 0)
            buffer = (char*) malloc(len);
        strcpy(buffer,txt);
    }
    void add(const char * txt){
        realloc(buffer,len+strlen(txt));
        strcpy(buffer+len,txt);
        len += strlen(txt);
    }
    ~String(){ if (len > 0) free(buffer);} // if commented it works fine !!!
    char* get_ptr(){ return buffer;}
private:
    char * buffer;
    int len;    
};

int main(){
    String s("Hello");
    s.add(" World");
    printf(s.get_ptr());
    getchar();
}

1 个答案:

答案 0 :(得分:1)

std::realoc有一个返回值,该值返回指向重新分配的存储区的指针。如果缓冲区后面有足够的可用空间,则该地址可以与输入地址相同,也可以是新地址。

因此,如果realloc(buffer,len+strlen(txt));返回的指针与buffer中存储的指针不同,那么您将继续使用无效的指针,这将导致未定义的行为。因此,对于可以工作的PC,可能是因为realloc返回了相同的指针,或者仅仅是因为未定义的行为确实导致了“正确”的结果。

更改代码(从析构函数添加/删除代码)将导致不同的内存布局,这也可能导致未定义行为的不同结果。

无论如何,realloc是用c ++解决该问题的错误方法。您应该在此处使用std::string(如果不想使用字符串,但是可以调整大小的缓冲区,则可以使用std::vector<char>