2010-04-28 3 views
1

동적으로 힙에 메모리를 할당하고 할당 된 메모리를 삭제하려고합니다. 컴파일러는 CharArray을 삭제하려고 할 때 다음C++ 초보자 코드 삭제

// String.cpp 
#include "String.h" 

String::String() {} 

String::String(char* source) 
{ 
this->Size = this->GetSize(source); 
this->CharArray = new char[this->Size + 1]; 
int i = 0; 
for (; i < this->Size; i++) this->CharArray[i] = source[i]; 
    this->CharArray[i] = '\0'; 
} 

int String::GetSize(const char * source) 
{ 
int i = 0; 
     for (; source[i] != '\0'; i++); 
     return i; 
} 

String::~String() 
{ 
delete[] this->CharArray; 
} 

내가 오류입니다 : 다음은 나에게 어려움을주고있다 코드가

가 0xc0000005 : 액세스 위반 위치 0xccccccc0을 읽고.

그리고 여기 스택의 마지막 호출입니다!

msvcr100d.dll 운영자가 삭제 (무효 * pUserData) 라인 52 + 0x3으로는 바이트 C++

나는 꽤 확신 이 코드 안에 오류가 있지만 필요한 다른 정보를 제공 할 것입니다. 오, 예, VS 2010 for XP를 사용합니다.

편집 : Heres는 내 String.h는

// String.h - string class 
#pragma once 

#define NOT_FOUND -1 

class String 
{ 
public: 
    String(); 
    String(char* source); 
    static int GetSize(const char * source); 
    int Find(const char* aChar, int startPosition = 0); 
    ~String(); 
private: 
    char* CharArray; 
    int Size; 
}; 
+1

기본 구성을 마치면'CharArray'의 값은 무엇입니까? – GManNickG

+1

이것을 사용하는 곳에 코드를 게시 할 수 있습니까? CharArray가 초기화되지 않은 채로있는 기본 생성자를 사용하여 코드를 작성한 것으로 의심됩니다. – kibibu

+1

그냥 회원이라고 말할 수있는 이유는이 -> 회원입니까? – tiftik

답변

5

기본 ctor를 변경하십시오. 오류가 발생하면 삭제 호출은 초기화되지 않은 포인터를 삭제하려고합니다.

String::String() : Size(0), CharArray(NULL) {} 

또한 "복사 생성자"를 유의하십시오. 암시 적으로 트리거하지 않도록 비공개로 설정할 수 있습니다. (호출 할 의도가 없다면 구현할 필요가 없으며 함수 프로토 타입을 클래스 정의에 붙이면됩니다.) 마찬가지로 대입 연산자를 "비활성화"할 수도 있습니다.

class String 
{ 
    // other stuff 

private: 
    String(String&); 
    String& operator=(String&); 
}; 

이 추가 모든 클래스가 소멸자, 복사 생성자 또는 할당 연산자를 필요로하는 경우, 그것은 아마 세 가지를 모두 필요하다고 말한다 "세 가지의 규칙"을 충족합니다.

편집 : 여러 생성자가 http://en.wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29

+0

정보 주셔서 감사합니다! 위의 조언과 함께이 문제를 해결하고 내 문제를 해결하는지 알려주도록하겠습니다. – Pooch

+0

생성자의 멤버 초기화에 대한 귀하의 집단적 조언은 원래의 문제점을 해결했습니다. 그런 다음 '='연산자를 제대로 구현하지 않아서 발생한 또 다른 오류가 발생했습니다. 하! 3 가지 규칙이 이유가 있다고 생각해보십시오. 도와 주셔서 다시 한번 감사드립니다! – Pooch

+0

LOL, 참으로 3의 규칙은 나가 진실하게 그것을 받아들이 기 전에 오히려 저에게 많게 설명했다. :) –

0

생각 @ 대시 - 톰 - 빅뱅이 올 것입니다. 아마도 String을 복사 한 다음 데이터를 두 번 삭제할 것입니다. 그래도 내 오래된 대답을 참조 용으로 유지하겠습니다.

당신은 String 사용하는 코드를 게시 할 필요 해요,하지만 난 여기에 몇 가지 문제가 나타날 수 있습니다

  1. 무엇 source 경우 생성자에 NULL입니까? 즉시 널 포인터 예외가 발생합니다. 더 나쁜 것은이 예외가 발생하면 소멸자가 할당되지 않은 메모리를 삭제하려고 시도한다는 것입니다. try ... catch을 사용하는 경우 위에 설명 된 오류가 발생할 수 있습니다.

  2. GetSize은 멤버 변수를 사용하지 않기 때문에 String의 멤버 함수가 아니어야합니다. 최소한 static이어야합니다. 어떤 경우에는 당신이 초기화되지 않은 포인터를 삭제하고, 그래서

+0

'std :: string'은 NULL 포인터를 전달하는 것을 좋아하지 않습니다 ... –

+0

... 아무도 NULL을 전달하지 않는다고 가정하는 것이 안전합니다 당신이 할 수 있다고 말하지 않는 한. 또한 기본적으로 NULL 액세스와 같은 예외 작동은 C++ 예외를 발생시키지 않습니다. 즉시 종료됩니다. – Potatoswatter

2
String::String(): CharArray(0) {} 

당신은 모든 생성자에서 CharArray을 초기화 아닙니다.

0

볼 수 있지만 그 중 하나가 새로운 호출합니다. 소멸자가 항상 delete를 호출하므로 오류가 발생합니다.