수업에 오류가 있습니다. 나는 그것이 단순하다고 생각합니다. 아마도 C ++에서 문자열이 어떻게 작동하는지 이해하지 못할 수도 있습니다. 내 함수는 로컬 std :: string을 다른 std :: string으로 반환하려고 시도하지만 문자열을 가져 오는 대신 함수가 반환 된 후 분할 오류가 발생합니다. 이것은 내 코드입니다.
TestClass::TestClass(std::string a, std::string b)
{
m_a = a;
m_b = b;
}
std::string TestClass::stringHandler()
{
const char myTemplate[] = "a=%s,b=%s";
char formattedString[strlen(myTemplate) + m_a.length() + m_b.length()];
sprintf( formattedString, myTemplate, m_a.c_str(), m_b.c_str());
std::cout << "formattedString= " << formattedString << "\n";
std::string returnStr(formattedString);
std::cout << "returnStr=" << returnStr << "\n";
return returnStr;
}
int main(...)
{
/* getting a and b from argv */
TestClass MyClassObj(a, b);
std::string strRet = MyClassObj.stringHandler();
std::cout << "Back after stringHandler\n";
return 0
}
stringHandler에서 returnStr을 인쇄 할 때 제대로 표시됩니다. 하지만 그 직후에 Segmentation 오류가 발생하고 "Back after stringHandler"가 인쇄되지 않습니다. 마스터 여러분, 내가 뭘 잘못하고 있는지 아는 사람이 있습니까?
몇 가지 문제 :
%b
유효한 형식 지정자가 아닙니다.%b
있지만 (고정 된 경우 !) 2 개의 인수 만 전달했습니다.formattedString
.(업데이트 :) OP에 대한 편집 후, 이들 중 처음 세 개가 수정되었으므로 컴파일러에도 런타임 배열 크기에 대한 확장이있는 경우이 코드는 segfault를 유발하지 않습니다.
가장 간단한 수정은 다음과 같이 작성하는 것입니다.
std::string returnStr = "a=" + m_a + ",b=" + m_b;
그러나 printf
서식 을 고수하고 싶다고 가정하면 여기에 한 가지 방법이 있습니다. 정확한 공간을 계산하고 계산하는 것은 가능하지만 취약합니다. .NET을 변경하면 버퍼 오버플로가 발생하기 쉽습니다 myTemplate
.
한 가지 계획은 많은 공간을 할당하는 것입니다. 보다 강력한 방법은 snprintf
먼저 버퍼 크기를 결정하는 데 사용 하는 것입니다 .
char const myTemplate[] = "a=%s,b=%s";
size_t expect_len = std::snprintf(NULL, 0, myTemplate, m_a.c_str(), m_b.c_str());
if ( expect_len == -1 )
throw std::runtime_error("snprintf failed");
std::vector<char> buffer(expect_len + 1);
std::snprintf(&buffer[0], buffer.size(), myTemplate, m_a.c_str(), m_b.c_str());
std::string returnStr(buffer);
11 ++ C에서 당신은 실제로 수 snprintf
직접적으로 returnStr
.
명확하게 말하면, 예상하지 못한 내용이 포함 된 printf
경우 정의되지 않은 동작을 유발할 수 있으므로 전체 아이디어는 매우 안전 myTemplate
하지 않습니다. (런타임에 다른 형식 문자열을 지정할 수 있도록이 방법을 사용했다고 가정합니다.) 따라서주의해서 사용하십시오.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다