strcat函数越界的问题

    技术2022-05-20  59

    首先,这是一个非常有趣的问题!我也是最近看了一本《C++高效编程:内存与性能优化》的书才弄明白其中的奥秘!我们先来看一个“奇怪”的现象:

    CODE:

            struct A { char a; long b; char c; long d; };        struct B { char a; char c; long b; long d; };        cout << sizeof(A) <<endl;        cout << sizeof(B) <<endl;按照常理,输出都应该是 10 ,其实实际运行结果是16,12 !是不是很奇怪???为什么会出现这个现象呢?因为编译器会强制char类型的变量与long类型的变量在内存中对齐!举例看结构A在内存中的布局如下:地址   内 容00     字符a01     未用02     未用03     未用04     long b, byte 005     long b, byte 106     long b, byte 207     long b, byte 308     字符c09     未用......可以看到其中的原因了吧!再看看LZ的程序的原因。C++的系统函数strcat()的功能只是简单的拼接字符串,自身没有检测是否越界的功能!所以,当拼接后的新的字符串长度大于原始的空间时,strcat()会修改邻接的内存空间!所调用strlen()所取得的长度是截止到 '/0' 的长度!但是调用sizeof()会发现其空间大小还是10!按照上面的说法,字符数组a后面的空间应该被修改,所以b的内容会变化,但是C++编译器分配内存空间是按照倒栈的顺序的,如果把b放到a前面定义,才有可能被修改!但是由于开始说的内存对齐问题的存在,因此字符数组b的内容还是没有被改变。大家可以看看下面的程序,分别输出a,b的地址。

    CODE:

    int main(){    char b[10] = "good";    char a[10] = "java is";    strcat(a," ");    strcat(a,b);     cout << int(&b) << endl;    cout << int(&a) << endl;    return 0;}运行结果为:22936002293584(该运行结果取决于不同的机器与编译器,但是反映的问题还是很明显的!)a,b的头地址相距16Byte,而a的默认空间只有10Byte,还有6Byte的空间是什么呢?当执行strcat()时,越界的部分就覆盖了这6Byte的内容,但是还没有影响到b的内容,为了证明strcat()确实存在越界的问题,我们可以构造一个特例,程序如下:

    CODE:

    int main(){    char b[30] = "good, but i don't think so!";    char a[10] = "Java is";    strcat(a," ");    strcat(a,b);    cout<<a<<endl;    cout<<b<<endl;     cout << int(&b) << endl;    cout << int(&a) << endl;    return 0;}我们把b放得足够大,然后调用strcat(),使得拼接后的字符串的长度大于16,这样的话,不仅仅是a,b之间的6Byte被覆盖,b的内容也被覆盖了!程序运行结果如下:Java is good, but i don't think so!t i'dont think so!可以看到,越界是存在的!最后总结一下:strcat()存在越界的问题,因此我们在使用该函数之前需要确保目标字符数组的空间足够大!在原始的程序中,由于变量较少,运行似乎没错,但是还是有很严重的BUG的!


    最新回复(0)