c++ - 类析构函数改变程序结果
问题描述
如果我评论析构函数并且它打印“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();
}
解决方案
std::realoc有一个返回值,它返回指向重新分配的内存区域的指针。如果缓冲区后面有足够的可用空间,则此地址可以与输入地址相同,也可以是新地址。
因此,如果realloc(buffer,len+strlen(txt));
返回的指针与存储的指针不同,buffer
那么您将继续使用无效指针,从而导致未定义的行为。因此,对于它工作的 PC,可能是因为realloc
返回了相同的指针,或者只是因为未定义的行为确实导致了“正确”的结果。
更改代码(从析构函数中添加/删除代码)将导致不同的内存布局,这也可能导致未定义行为的不同结果。
不管怎样,realloc
在 C++ 中解决该问题的方法是错误的。你应该std::string
在这里使用(或者std::vector<char>
如果不想有一个字符串,而是一个可以调整大小的缓冲区)。
推荐阅读
- c# - 连接表中不存在实体框架选择记录或字段为空
- python - Django SQLite 视图返回空查询集 []
- python - Django:在models.py上使用apps.get_model获取模型
- ios - 如何在 iOS 后台使用相机
- angular - 角度业力测试 indefined id
- javascript - GNU gettext 无法从 Javascript 中提取字符串
- java - 可选的
- > 对于存储库层中的空列表返回 Optional.empty 。如何将其更改为返回 Optional[[]]
- java - 在 Android 中设置 Firebase 测试数据库
- reactjs - React Native:自定义标签栏
- java - 如何从服务器使用 Cloud Messaging Firebase 推送通知