關於strcpy()函數在拷貝字符串數組的時候出現的大小不匹配問題和數組值改變問題


問題的來源是自己寫的一個測試代碼:

#include <iostream>
using namespace std;

int main() {
    char a[1];
    a[0] = 'a';
    a[1] = 'b';

    char b[1];
    b[0] = 'c';
    b[1] = 'd';

    strcpy(a, b);
    cout<<"拷貝之后:a[0] = "<<a[0]<<"    a[1] = "<<a[1]<<endl;
    cout<<"拷貝之后:b[0] = "<<b[0]<<"    b[1] = "<<b[1]<<endl;
    return 0;
}

在這之后輸出的兩個字符串的值並不是想象中的:

“拷貝之后:a[0] = c  a[1] = d

 拷貝之后:b[0] = c  b[1] = d”

而是:

一開始看到之后一臉懵逼,為啥我用strcpy()拷貝完之后,源字符數組的值反而不對了呢?

於是我多寫了一些測試用的輸出代碼,和顯示兩個字符數組頭在內存中位置的輸出代碼來找出問題所在:

#include <iostream>
using namespace std;

int main() {
    char a[1];
    a[0] = 'a';
    a[1] = 'b';
    cout<<"a[0] = "<<a[0]<<"    a[1] = "<<a[1]<<endl;

    char b[1];
    b[0] = 'c';
    b[1] = 'd';
    cout<<"聲明char b[1]后:a[0] = "<<a[0]<<"    a[1] = "<<a[1]<<endl;
    cout<<"b[0] = "<<b[0]<<"    b[1] = "<<b[1]<<endl;

    strcpy(a, b);
    printf("%x\n",a);
    printf("%x\n",b);
    cout<<"拷貝之后:a[0] = "<<a[0]<<"    a[1] = "<<a[1]<<endl;
    cout<<"拷貝之后:b[0] = "<<b[0]<<"    b[1] = "<<b[1]<<endl;
    return 0;
}

隨后得到了輸出如下:

可見,在聲明完char b[1]這個小婊砸后,字符數組a中的值就已經被改變了!

這是為什么呢?

可以看到,a和b這兩個字符數組的地址相差只有1,這也就是問題的所在了!

在剛聲明完char a[1]時,內存中是這樣的:

53151adb  'a'   // 這里是字符數組a的開始地址

53151adc  'b'

53151add  '\0'

而等到char b[1]聲明完后,內存中變成了這樣:

53151ada  'c'   // 這里是字符數組b的開始地址

53151adb  'd'   // 這里是字符數組a的開始地址,原來的 'a' 被字符數組b中的 'd' 覆蓋了!

53151adc  '\0'  // 原來的'b'被字符數組b中的結尾符'\0'覆蓋了!

53151add  '\0'

這就解釋了為什么char b[1]聲明完后,a[1]變成了'd'的問題。

那么當我們使用了strcpy(a, b)會怎么樣呢?

這個函數會把b中的值一個個復制到a中去,因此復制完之后內存地址長這樣:

53151ada  'c'   // 這里是字符數組b的開始地址

53151adb  'c'   // 這里是字符數組a的開始地址,剛剛的 'd' 被字符數組b中的 'c' 覆蓋了!

53151adc  'd'   // 剛剛的'\0'被字符數組b中的'd'覆蓋了!

53151add  '\0'

這時候,再輸出字符數組a和b的時候,就呈現了一開始我們看到的一坨&%&%¥%@……嗯。

歡迎大家在評論區留言交流~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM