首页 > 解决方案 > 类析构函数改变程序结果

问题描述

如果我评论析构函数并且它打印“Hello world”如果没有评论它打印“Hello”,那么下面的代码可以正常工作!注意我在 windows xp 32bits 上使用 mingw 4.9 并且机器非常旧 pintume 4 1.8ghz

奇怪的是,这段代码在其他现代电脑上运行正常,我只在这台旧电脑上得到这个错误

#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();
}

标签: c++

解决方案


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

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

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

不管怎样,realloc在 C++ 中解决该问题的方法是错误的。你应该std::string在这里使用(或者std::vector<char>如果不想有一个字符串,而是一个可以调整大小的缓冲区)。


推荐阅读