문제 소개

과제1에서는 C++로 나만의 문자열 클래스를 작성합니다. 이 과제에서 STL 컨테이너, std::string , cstring 헤더는 사용이 금지됩니다. c-style string과 직접 메모리 관리를 통해서만 구현해야 합니다.

본 문서에서는 MyString 클래스를 구현하면서 고민한 부분들과 해결한 문제들에 대한 내용을 담고 있습니다.

GetCString 메서드의 적절한 반환형 고르기

GetCString 메서드는 개체 내부에 저장된 문자열을 C 스타일 문자열(null-terminated string)로 반환합니다. 이는 기존 C의 string 라이브러리와의 호환을 위해서도 필요합니다. 그러나 단순한 char*로 반환해서는 호출자가 아래와 같이 개체의 일관성을 깨뜨릴 수 있습니다.

따라서 반환형은 char*보다는 const char*로 하여 호출자에게 참조만 가능하고 수정은 금지된다는 것을 명확히 보여주는 것이 좋습니다.

덧붙이면, C++ 표준 라이브러리인 std::string클래스의 c_str 메서드 또한 const char*를 반환하도록 하고 있습니다.

std::basic_string<CharT,Traits,Allocator>::c_str - cppreference.com

불필요한 메모리 할당

Append(const char* s), Interleave(const char* s)와 같은 메서드는 기존 문자열의 길이를 변경하기 때문에, 내부적으로 더 큰 메모리를 동적 할당한 뒤 기존 데이터를 복사하고, 이전 메모리를 해제하는 작업을 수행합니다.

하지만 매개변수로 empty string이 전달될 경우, 실제로 문자열에 변화가 없으므로 이러한 과정은 불필요한 연산 및 메모리 낭비로 이어집니다.

// BEFORE: empty string에 대해 불필요한 할당 및 복사가 일어남
void MyString::Append(const char* s)
{
	// 힙 할당 및 복사, 기존 메모리 해제
}

이를 방지하기 위해, 매개변수로 empty string이 전달될 경우 early return하도록 구현하여, 불필요한 힙 할당 및 복사를 방지했습니다.

// AFTER: empty string이 전달되면 조기 반환
void MyString::Append(const char* s)
{
	size_t sLength = strlen(s);
	if (sLength == 0)
	{
		return;
	}

	// 힙 할당 및 복사, 기존 메모리 해제
}

unsigned 자료형의 underflow 문제

IndexOf(const char* s) 메서드에서 s의 길이가 개체에 저장된 문자열의 길이보다 클 경우, searchCount의 초기값은 음수값이 되어야 합니다. 그러나 searchCount의 자료형은 size_t(unsigned int)로, underflow가 발생하여 UINT_MAX에 가까운 매우 큰 수가 저장됩니다.

이러한 상황에서 start < searchCount 조건은 계속 true가 됩니다. 이는 반복문이 버퍼 범위를 넘어 접근할 수 있는 위험한 연산입니다.