2010-07-29 3 views
3

에 의해 구조체 또는 객체를 전달 나는이 있습니다C++ 값

enum Units { Pounds, Kilos }; 

struct Configuration 
{ 
    const Units units; 
    const char *name; 

    inline Configuration(Units pUnits, char *pName) : units(pUnits) 
    { 
     name = strdup(pName); 
    } 

    inline ~Configuration() { free((void *)name); } 
}; 
나는이 같은 방법으로이 중 하나를 통과했다

:

Configuration cc(Kilos, "abc"); 
cdao->write(cc); 
내가 시도 할 때까지이에서 심한 충돌을 얻고 있었다

참조 방법을 재정의하십시오.

Configuration cc(Kilos, "abc"); 
cdao->write(&cc); 

이제 모든 것이 작동합니다.

하지만 구조체가 값으로 메모리를 망칠 수 있습니까?

+0

'std :: string name'을 멤버로 사용하고 소멸자를 전혀 쓰지 말아야합니다. –

답변

2

사용자가 직접 복사 생성자 또는 할당 연산자를 제공하지 않았습니다. 복사 나 할당을 할 때 컴파일러에서 생성 한 복사 생성자와 대입 연산자가 사용됩니다. 실제로이 경우 올바른 작업을 수행하지 못합니다. 그들은 모든 구성원을 복사하여 과 동일한 문자 배열을 참조하는 두 개의 Configuration 객체로 끝납니다. 그리고 두 Configuration 객체는 배열 삭제에 대한 책임이있어서 거의 확실하게 "이중 삭제"오류가 발생합니다.

"rule of three"에 유의하십시오. 여기서 문제는 포인터가 원하는대로 동작하지 않는다는 것입니다. std :: string을 멤버로 사용한 경우 자신의 복사본 생성자, 소멸자, 대입 연산자를 작성할 필요가 없습니다. 왜냐하면 컴파일러가 생성 한 것들은 멤버들에 대한 관련 연산을 호출하기 때문이며 문자열 멤버는 char에 대한 포인터와 달리 이미 이것을 올바르게 처리하기 때문입니다.

+0

대단한 답변 모두,이게 더 좋을 것 같아. 감사. –

6

strdup를 사용한다는 사실은 코드에 이상이 있음을 나타내며 잘못된 것은 복사 생성자가 없다는 것입니다. 언제든지 소멸자가 있으면 거의 값으로 호출 할 때 객체를 올바르게 복사하는 복사 생성자가 필요합니다.

은 당신의 코드를 개선하려면

  • 가 할당 복사 생성자와 아마 할당 연산자를 만들고에서는 StrDup 제거, 제대로

  • 더 좋은 방법은 문자열을 복사 - 성병을 사용합니다 :; 이 경우에는 소멸자, 사본 또는 할당 op가 필요하지 않습니다.

  • "인라인"키워드를 제거하십시오. 그들은 아무 것도하지 않습니다.

+0

인라인 키워드는 클래스의 "외부"로 선언 된 메서드 정의에 사용될 때 의미가 있습니까? –

+0

@German 주로 - 인라인을 사용하는 유일한 이유는 하나 이상의 번역 단위에서 함수 소스를 # 포함하는 경우입니다. –

1

당신은 복사 units*name의 내부 *name 아닌 값, 참조 밖으로 호출합니다. 따라서 임시 객체가 파괴되면 의 모든 인스턴스에서 해방 된 *name이 해제됩니다.

1

구조체에 복사 생성자를 추가하고 char * name을 처리해야합니다. (평균, 메모리 할당 및 삭제, 값으로 초기화).

어쨋거나 문자열에 char *을 사용하는 것은 좋지 않습니다. std :: string을 사용하면 모든 것을 처리 할 수 ​​있습니다.

+0

학생이 아래에서 위로 언어를 배우는 것이 좋습니다. 그가 std :: string을 아직 가지고 있다면 그는 복사 생성자에 대해 배울 이유가 없을 것입니다. –

+0

그리고 아마도 그가 좋아하지 않을지 모르지만 (지금 배우기). 아마 당신이 하나를 창조하지 않고 아주 멀리 갈 수 있고, 그리고 당신이 정말로 필요할 때 그것을 배우는 것이 더 나을 것입니다. –

+0

그래 ... 나는 오랫동안 C++에 손대지 않았고, 나는 어쨌든 C에 더 가까웠다. 전에는이 문제를 놓고 본 적이 없었습니다. 나는 항상 ref로 객체를 전달했다고 생각합니다. 그리고 네, 무슨 일이 벌어지고 char *로 작동하도록해야하는지 이해하는 것을 선호합니다. 모두에게 감사드립니다. –