C++ string class 에서 메모리 관리는 어떻게 하나요?

trymp의 이미지


  string s = "ABC";

  char buf[1024];
  memset(buf, 'A', sizeof(buf));
  s = buf;

size 가 다른 위의 두가지 경우 모두 heap 으로 할당받아서 관리하나요?

아니면 기본적으로 string 이 가지고 있는 고정버퍼가 따로 있고 over 하는 경우에만 heap 으로 할당받나요?

또 append 인 경우는 realloc 후 다시 merge 하는 것인지??

string class 내부에서 메모리 관리를 어떤 식으로 하는지 궁금합니다.

조언 부탁드립니다.

mauri의 이미지

기본적으로 문자열을 대입시키면 버퍼를 alloc해서 문자열을 넣어주고요.
alloc해놓은 버퍼보다 더 큰 문자열이 들어오면 realloc해서 머지해 줍니다.

realloc 과정이 부담이 큰 작업이기 때문에 일반적으로 대입받은 문자열의 길이만큼만 할당하는 것은 아니구요.
(라이브러리마다)각각의 기준에 따라 조금더 할당받아서 부담을 줄이는 방식을 취하고 있습니다.

극단적이게 1, 2, 4, 8, 16, 32, 64식으로 버퍼를 늘일 수도 있구요.
string str = "1234" -> size = 4
str += "5" -> size = 8

그냥 소심하게 하위 4비트만 마스크해줘서 버퍼를 늘일 수도 있구요.
string str = "123" -> size = 15
str += "4567890123456" -> size = 31

이건 엿장수(만든사람) 맘이겠지요.

참고로, 질문하시는것보다 직접 보시는게 더 도움이 되실듯 싶으니까요.
직접 열어보시기 바랍니다.

익명 사용자의 이미지

사실 C++ 표준에서는 std::string을 어떻게 구현하라고 명시해 놓지 않았기 때문에 내부 구현은 엿장수 마음대로가 맞긴 합니다. Effective C++였나 이걸 본 책 제목은 기억이 안 나는데, 일부 구현 중 내부 버퍼를 사용해서 짧은 길이 문자열에 최적화시키는 게 있었기 때문에 이게 아주 말이 안 되는 이야기는 아닙니다.

shint의 이미지

string 과 char 배열 복사를 확인하던중. 생각보다 사용하기 어렵다는것을 알게 되었습니다. (물론. 잘못 사용해서 겠죠.)
하여간. 이것을 참고해보시기 바랍니다.

출력 결과를 포함한. 소스를 파일로 첨부합니다.

memory clobbered past end of allocated block

Exited: ExitFailure 127

//http://stackoverflow.com/questions/7684449/stl-map-set-error-memory-clobbered-past-end-of-allocated-block
int* currSum= new int(sizeArr+1);
you probably meant
int* currSum= new int[sizeArr+1];

-----------------------
buf[5]
s = buf       AAAAA$)=
-----------------------
buf[5] = '\0'
buf[5+1]
s = buf      AAAAA
-----------------------
s = buf       AAAAA$)=
strcpy(s.c_str(), buf)       AAAAA$)=
-----------------------
strcpy(s.c_str(), buf)       AAA
-----------------------
s.append(buf)         ABCAAAAA$)=
strcpy(s.c_str(), buf)       AAAAA$)= )=
-----------------------
s.append(buf)         ABCAAAAA$)=
strncpy( (char*)s.c_str(), buf, 5)       AAAAAAAA$)=
-----------------------
s.clear()
strcpy(s.c_str(), buf)
strncpy( (char*)s.c_str(), buf, 5)
-----------------------
s.append(buf)         ABCAAAAA$)=
strcpy(s.c_str(), buf)       ABCAAAAA$)=
strncpy( (char*)s.c_str(), buf, 5)       AAAAAAAA$)=
-----------------------
s.append(buf,5)         ABCAAAAA
strcpy(s.c_str(), buf)       ABCAAAAA
strncpy( (char*)s.c_str(), buf, 5)       AAAAAAAA
-----------------------
s.clear()
s.append(buf,5)         AAAAA
strcpy(s.c_str(), buf)       AAAAA
strncpy( (char*)s.c_str(), buf, 5)       AAAAA

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

jick의 이미지

  char buf[1024];
  memset(buf, 'A', sizeof(buf));
  s = buf;

이 코드는 잘못된 코드입니다. buf의 마지막에 널문자가 없기 때문에 buf를 넘어서 널문자('\0')가 나올 때까지 끝없이 메모리를 읽게 됩니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.