-5

我正在为人们注册程序,我有重载运算符 = 的问题。

我有类CRegister、结构PersonPlace.

struct Places{
    char date[11];
    char * street;
    char * city;

Places & operator = (const Places & other){
        delete [] street;
        delete [] city;

        strncpy (date, other.date, 11);

        int len;
        len = strlen(other.street);
        this->street = new char[len];
        strncpy ( this->street, other.street, len );

        len = strlen(other.city);
        this->city = new char[len];
        strncpy ( this->city, other.city, len );

        return *this;
    }
}


struct Person{
    char id[12];
    char * name;
    char * surname;
    Places ** oldPlaces;

    int placesCount;
    int placesSize;
};

Person & Person::operator =(const Person& other){
    for (int i = 0; i < this->placesSize; i++){
         delete this->oldPlaces[i];
    }
    delete [] this->oldPlaces;
    delete [] name;
    delete [] surname;


    placesCount = other.placesCount;
    placesSize = other.placesSize;

    oldPlaces = new Places*[other.placesSize];

    strncpy (id, other.id, 11);

        int len;

        len = strlen(other.name);
        this->name = new char[len];
        strncpy ( this->name, other.name, len );

        len = strlen(other.surname);
        this->surname = new char[len];
        strncpy ( this->surname, other.surname, len );

    for (int i = 0; i < placesCount; i++){
        oldPlaces[i] = other.oldPlaces[i];
    }

    return *this;
}



class CRegister     
 {
   private:
    Person **persons;
    int personCount;
    int personSize;
 };

 CRegister& CRegister::operator =(const CRegister& other){
    for (int i = 0; i < this->personSize; i++){
        delete this->persons[i];
    }
    delete [] this->persons;

    personCount = other.personCount;
    personSize = other.personSize;

    persons = new Person*[other.personSize];

    for (int i = 0; i < personCount; i++){
        persons[i] = other.persons[i];
    }


    return *this; 
 }

但是,代码已编译,但 Netbeans 显示运行失败。为什么?

4

3 回答 3

2
    len = strlen(other.city);
    this->city = new char[len];
    strncpy ( this->city, other.city, len );

这不会保留字符串的长度。后面的代码怎么知道有多长this->city

于 2013-04-12T15:59:47.943 回答
1

你没有遵循三法则。如果不是唯一的原因,这可能是一个原因。

另一个注意事项,

于 2013-04-12T15:59:29.827 回答
1

由于您基本上使用的是 C(包装在一个类中):您已经犯了可能是 C 代码中最常见的错误。 strlen 返回字符串中的字符数,包括最后的'\0'. strcpy复制 final '\0',所以多了一个字符,如果你使用strncpy(你不应该这样做),那么你最终会得到一个没有 '\0'终止的字符串。因此,使用strcpy,您会超出缓冲区的末尾,并且使用strncpy,任何尝试读取字符串的人都将超出缓冲区的末尾(因为它们会一直持续到 a '\0')。

规则是分配比strlen 返回多一个字符:

size_t len = strlen( other.name ) + 1;
name = new char[ len ];
strcpy( name, other.name );

(虽然不是标准的 C,但许多系统都有strdup执行此操作的功能。malloc当然,使用 ,因此您必须使用 释放free,而不是delete。)

除此之外,我将重复我之前所说的:如果任何分配失败,您的代码将使对象处于不一致的状态。 在修改班级中的任何内容之前,请务必完成所有可能失败的事情。交换习语是经典的operator=,但除此之外,您可以使用本地指针:

char* newName = NULL;
char* newSurname = NULL;
Places* newPlaces = NULL;

try {
    newName = strdup( other.name);
    newSurname = strdup( other.surname );
    newPlaces = deapCopyPlaces( other.places );
} catch ( ... ) {
    deepDelete( newPlaces );
    delete [] newName;
    delete [] newSurname;
}
//  And only now...
deepDelete( places );
delete [] name;
delete [] surname;
name = newName;
surname = newSurname;
places = newPlaces;

但是交换习惯更可取,因为它避免了复制所有错误处理代码。

于 2013-04-12T16:35:13.803 回答