c++ 문자열 복사 관련 질문

조회수 1402회

헤더파일 Mystring.h

pragma once

class CMyString

{

public:

CMyString(void);

~CMyString(void);

private:

char* m_pszdata; // 메모리 저장 문자열

int m_nlength; // 문자열 길이

public:

int SetString(const char* pszparam);
const char* GetString();
void Release();

};


클래스 정의 cpp

include "stdafx.h"

include "MyString.h"

include "string.h"

CMyString::CMyString(void)

: m_pszdata(NULL)
, m_nlength(0)

{ }

CMyString::~CMyString(void)

{

Release();

}

int CMyString::SetString(const char* pszparam)

{

Release();
static char str[7] = "Error!"; // 오류시 출력할 문자열 변수 선언
m_nlength = strlen(pszparam); // 문자열 길이 값 저장 OK
m_pszdata = new char[m_nlength+1]; // 문자열의 길이만큼 메모리 동적 할당 (NULL 문자를 포함하기 위해 +1 )

if(m_nlength==0 || pszparam == NULL) m_pszdata = str; // 문자열 길이가 0 이거나 문자열이 NULL 일때 Error 문구대입
else //strcpy_s(m_pszdata, sizeof(char)*(m_nlength+1),pszparam); 
    // 매개변수의 문자열을 m_pszdata 동적메모리에 복사 ( NULL문자까지 복사해야하므로, m_nlength + 1 )
    m_pszdata = (char*)pszparam; // const char* → char* 강제형변환 뒤 char* 형식 m_pszdata 에 메모리주소 저장
return 0;

}

const char* CMyString::GetString()

{

return m_pszdata;

}

void CMyString::Release() {

if(m_pszdata!= NULL)
delete[] m_pszdata;

m_pszdata = NULL;
m_nlength = 0;

}


메인 cpp

include "stdafx.h"

include "MyString.h"

int _tmain(int argc, _TCHAR* argv[]) {

CMyString strData;
strData.SetString("hello");
cout << strData.GetString() << endl;
strData.SetString("byegg4");
cout << strData.GetString() << endl;
return 0;

}

클래스 정의 cpp 코드에서 매개변수로 받은 문자열을 m_pszdata 에 복사하는 과정을 구현하려고 했습니다.

정답부 처럼 strcpy_s(m_pszdata, sizeof(char)*(m_nlength+1),pszparam);
이렇게 구현하면 Release 메서드를 호출해도 문제가 없는데

제가 구현한 방식대로

m_pszdata = (char*)pszparam; // const char* → char* 강제형변환 뒤 char* 형식 m_pszdata 에 메모리주소 저장

이런식으로 구현하면 사진과 같은 오류가 발생합니다...

이미지

혹시나 문자열에 NULL문자가 제대로 안들어갔나 확인해봤지만 그문제도 아닌거같습니다. 제가구현한 방식의 문제가 무엇일까요 ??...

  • (•́ ✖ •̀)
    알 수 없는 사용자

1 답변

  • strcpy_s(m_pszdata, sizeof(char)*(m_nlength+1),pszparam); 이렇게 구현하면 Release 메서드를 호출해도 문제가 없는데

    제가 구현한 방식대로 m_pszdata = (char*)pszparam; // const char* → char* 강제형변환 뒤 char* 형식 m_pszdata 에 메모리주소 저장

    ==> 이미 m_pszdata는 new로 메모리를 할당 받았는데, 포인터를 할당해서 문제가 될거같네요. pszparam 포인터에서 할당한 m_pszdata로 메모리 복사를 해야할거같습니다. SetString에서 포인터 주소만 가져올경우, 콜한함수가 종료되거나, delete되면 데이터 유실이 발생하여, GetString으로 정상적인 데이터를 가져올수없으며, segment 오류가 발생할수있습니다

    • 답변 감사합니다. 답변을 보고 생각을 해봤는데 , 제가 동적메모리 할당 개념이 부족해서 동적메모리에 포인터를 할당하는 것이 어떻게 문제가 되는 이해하기 조금 어렵네요... 혹시 조금 이부분에 대해서 자세히 설명해주실수 있을까요..? 알 수 없는 사용자 2020.3.5 00:54
    • 포인터는 데이터가 아니라 주소예요. 포인터를 가져갔다고 데이터를 가져간건 아니죠. 데이터를 가져올수있는 주소를 가져온거에요 문철민 2020.3.9 10:35
    • 동적메모리할당은 포인터에 얼마만큼의 공간을 확보하는거고, 그 공간은 해제하기전까지 유효합니다. 포인터에 동적메모리를 할당 받았으면, 그 포인터는 건들면 메모리 오류가 발생합니다. 이미 할당이 되어있으므로 공간으로써 사용해야지 포인터를 대입하면 안됩니다. 다만 동적으로 할당된 포인터에 데이터를 넣고 다른곳에서 읽는방식으로 이용해야죠 문철민 2020.3.9 10:39
    • 아.. 동적메모리 공간이 할당된 포인터 변수(m_pszdata)에 다른 문자열의 포인터(pszparam)를 할당하려니까 문제(Crush 오류 외에도 동적메모리를 할당하고 사용하지 않는 비효율적인 문제)가 발생된다는 말씀이시군요... 이해했습니다. 친절한 답변 감사합니다!! 알 수 없는 사용자 2020.3.9 20:07

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)