1

c2.view()を呼び出すと、顧客IDのIDと名前の両方が出力されるのはなぜですか?

私はしばらくこれを見つめていましたが、原因を見つけることができませんでした。私は本当に明白な何かを見逃したか、cstringsがどのように機能するか理解していません:)

Customer.h

#ifndef CUSTOMER_H
#define CUSTOMER_H
 class Customer
 {
 private:
     char accountID[6];
     char name[30];
 public:
     Customer();
     Customer(char[], char[]);
     void view();
     Customer operator=(const Customer&);

 };
#endif

Customer.cpp

#include <string>
#include <iostream>
#include "Customer.h"
using namespace std;



Customer::Customer()
{
    strcpy(accountID, "");
    strcpy(name, "");
}

Customer::Customer(char acc[], char n[])
{
    strcpy(accountID, acc);
    strcpy(name, n);
}

void Customer::view()
{
    cout << "Customer name: " << name << endl;
    cout << "Customer ID: " << accountID <<endl;
}

Customer Customer::operator=(const Customer& right)
{
    strcpy(accountID, right.accountID);
    strcpy(name,  right.name);
    return* this;
}

Driver.cpp

#include <iostream>
#include "Customer.h"
using namespace std;

int main()
{
    char id[] = "123456";
    char n[] = "Bob";
    Customer c1;
    Customer c2(id, n);
    c1.view();
    c2.view();
    system("pause");
    return 0;
}

出力:

Customer name:
Customer ID:
Customer name: Bob
Customer ID: 123456Bob
Press any key to continue . . .
4

4 に答える 4

4

7文字の文字列を渡します。

char id[] = "123456"; // one more character for null termination '\0'

ただし、配列のサイズは6です。したがって、を印刷するときはaccountId、文字を超えて、その'6'隣にあるものをすべて印刷します。この場合は、。の内容になりnameます。

std::strings文字配列の代わりに使用することで、多くの問題を回避できます。

于 2012-11-27T22:22:18.990 に答える
1

C++を使用しますstd::string。あなたはaccountIDメンバーの境界を越えて書いています。これchar id[] = "123456";には7つの要素があります。

この場合に発生するのは、終了するnull文字が最初に終了しname[0]、次にによって上書きされて、strcpy (name, n)1つの連続したシーケンスを取得することです。123456Bob\0

于 2012-11-27T22:22:26.493 に答える
1

accoutIDは長さが6に短縮されているため、nでstrcpyを実行すると、name[0]にオーバーフローしたaccountIDのターミネータが上書きされます。

于 2012-11-27T22:24:18.573 に答える
1

strcpyヌルターミネータに到達するまでコピーします。\0何も定義されておらず、デバッグを実行しているため、nameはidに隣接するメモリを占有し、idのバッファにもコピーされています。

リリースをビルドする場合、おそらくそこにがらくたがあるでしょう。いずれにせよ、C文字列を使用している場合は、すべての文字列の最後にnullターミネータが必要です。

strcpyの実装は次のようなものです。

while (*ptr2 != '\0')
{
    // copy string2 into string1's buffer until we reach it's null termintor
    *ptr1 = *ptr2
    ptr1++;
    ptr2++;
}
*(ptr1 + 1) = '\0'  // append null terminator

ご覧のとおり、これはnullターミネータに依存しており、存在しない場合はバッファオーバーフローが発生します。

于 2012-11-27T22:24:39.963 に答える