目标字符串空间不足所出现的问题
#include<iostearm>
#include<cstring>
using namespace std;
int main()
{
const char *pa="A string example";
const char *pb="A different string";
char largestr[30]; //空间不足
strcpy(largestr,pa);
strcat(largestr," ");
strcat(largestr,pb);
cout<<largestr<<endl;
return 0;
}
为什么不报错,而且输出的结果也是正确的呢?
[解决办法]
能正常输出完全是运气。
楼主的代码在溢出后,没有覆盖别的代码,因此能正常输出。
总之,这样的行为是为定义的
[解决办法]
因为系统不自己判断数组越界,要自己去判断
[解决办法]
可是,多次测试均结果正常,奇怪了。
- C/C++ code
#include <iostream>#include <cstring>using namespace std;int main(){ const char *pa="A string example";const char *pb="A different string";char largestr[30]; //....strcpy(largestr,pa);strcat(largestr," ");strcat(largestr,pb);cout <<largestr <<endl; return 0;}
[解决办法]
谁能让他输出错误看看!
[解决办法]
想出现错误? 太简单了, 代码别放在main中, 放到一个子函数中就行了
因为溢出后会先覆盖EBP, 里面存放的是退出时的堆栈地址, 然后会覆盖返回地址, 最后会覆盖传入的参数. 所以如果放在子函数中就回不了main而是跳到一个天晓得的地方, 不出错才有鬼
[解决办法]
to Idle_:
- C/C++ code
#include <iostream>#include <cstring>using namespace std;int testfunc(){ const char *pa="A string exampleo";const char *pb="A different string";//cout <<strlen(pa)<<strlen(pb)<<endl;char largestr[30]; //....strcpy(largestr,pa);strcat(largestr," ");strcat(largestr,pb);cout <<largestr <<endl; return 0;}int main(){ cout<<"TEST STRING"<<endl; testfunc(); cout<<"TEST STRING END"<<endl; return 0;}
[解决办法]
生成一个release版
[解决办法]
其实防止堆栈溢出很简单, 就是在函数进入时多分配一块程序用不到的堆栈内存, 其中都填入特定内容(比如 vc就填的是0xCC), 这样就可以在函数退出前检测这块堆栈内存是否被改写来判断是否存在堆栈溢出. 所以, debug版本的溢出程序貌似运行正常并不表示溢出不存在, 只是说明了"溢"得还不够"出", 还没有达到破坏函数返回地址的地步。 而不加堆栈保护功能的RELEASE版本则必出问题。
[解决办法]
- C/C++ code
#include<iostream>#include<cassert>using std::cin;using std::cout;using std::endl;#define AST(msg,x) assert(msg && x)int main(int argc, char *argv[]){ const char *pa="A string example";//16 const char *pb="A different string";//18 char ch[34]={0}; char largestr[1]={0};//空间不足 AST("第一处的断言失败",ch[0]=='\0'&&ch[1]=='\0'); cout<<largestr<<'\n'<<ch<<endl; cout<<(void*)largestr<<'\n'<<(void*)ch<<endl; strcpy(largestr,pa); strcat(largestr," "); strcat(largestr,pb); cout<<largestr<<'\n'<<ch<<endl; AST("第二处的断言失败",ch[0]=='\0'&&ch[1]=='\0');////////////////////////////////////////////////////////// return 0;}