[C++]일반 포인터 vs 스마트 포인터

greathero의 이미지

KLDP에 계신 여러분들은 일반 포인터와 스마트 포인터를 어떻게 보시는지 궁금합니다.
구글링을 해보면 스마트 포인터는 기존에 C#/Java같이 G.C의 혜택을 받았던 개발자들에게
메모리 해제라는 짐을 덜어준 것이라고 알고 있습니다.

하지만, 멀티 스레드 환경에서는 reference-counting 방식의 포인터는
생성, 복사, 파괴 과정에서 원자적이어야 하므로 퍼포먼스가 저해될 수 있다고도 알고 있습니다.

그런데, 스마트 포인터 자체가 일반 포인터에 비해 많이 무거운지라(정말 스마트 포인터가 일반 포인터에 비해 많이 무거운가요?) 일반 포인터를 사용하는 것을 선호한다는 얘기도 줏어들었습니다.

지금까지 알고 있는 지식을 취합해보면 싱글 스레드 기반에서는 스마트 포인터를 써도 크게 무리는 없겠지만 멀티 스레드에서는 일반 포인터를 쓰는 것이 좋다.
이정도로 정리가 되는데 C++ 에서의 자원 관리 및 성능에 있어서 고수님들은 어떤 포인터를 쓰고 왜 쓰는지 이야기를 듣고 싶습니다.

kukyakya의 이미지

많이 무겁지 않습니다. 실제 환경에서는 포인터 자체를 복사하는 작업은 그 횟수가 많지 않아 오버헤드가 거의 없다고 보셔도 됩니다.

개인적으로 스마트 포인터의 사용을 많이 선호하는 편인데, 그 이유로는

1) error handling path가 여럿이라도 자원 관리가 편하다.
2) 자원을 해제하는 주체가 명확하지 않을 경우에도 사용이 편리하다.
3) 여러 custom memory allocator를 이용할 경우에, 객체를 사용하는 주체가 어떤 할당자를 사용하여 해제해야하는지 알 필요가 없다.

등이 있습니다.

jick의 이미지

unique_ptr도 스마트 포인터로 치는지는 잘 모르겠는데 (별로 스마트하지는 않죠 -_-) 이 경우 컴파일러가 제대로만 해주면 그냥 포인터를 쓰는 것과 동일한 코드가 나와야 합니다. 즉 오버헤드는 전혀 없고, 실수로 memory leak을 만들 가능성을 대폭 줄여주는 아주 좋은 기능이죠.

Reference counting을 하는 경우는 써본 적이 없어서 어쩔라나 잘 모르겠습니다. (분야에 따라 다르겠지만, 제 경우에는 클래스를 잘 설계하면 거의 모든 경우가 unique_ptr로 해결이 됩니다.)

익명 사용자의 이미지

눈곱만한 성능향상을 위해 안정성을 포기하시렵니까?

정말이지 new/delete를 직접 호출하는 C++ 프로그래머는 안 봤으면 좋겠습니다.

unique_ptr, shared_ptr, vector가 있는데 왜 수작업으로 하는지 모르겠습니다.

익명 사용자의 이미지

new 를 직접 호출 안하면 자동 호출이라도 해주나요? ㅋㅋ (joke)

twinwings의 이미지

최소한 코드 작성자 입장에서.

익명 사용자의 이미지

소스코드를 쓸데없이 기묘하게 만드는 난독화 방법인듯

twinwings의 이미지

언급한 예제는 다른 책이었나 봅니다. 정정하겠습니다. 문법이 비슷해서 헷갈렸군요. 링크는 다른 경우입니다..죄송합니다.

그리고, 방금 직접 돌려서 테스트해봤는데 역시나 ctor, move ctor 둘다 호출되서 효율상도 별로 안좋을 것 같습니다.

kukyakya의 이미지

C++11에 추가된 make_shared와 같은 함수를 이용하면 new를 호출하지 않아도 됩니다.

익명 사용자의 이미지

자바에서는 모든 인스턴스를 new로 생성하지만
C++은 지역변수로 선언하면 스코프룰에 따라서 소멸합니다

즉 C++에서 new(또는 스마트포인터)는 자바처럼 매번 쓰는게 아니라
필요한 경우에 쓰는 것이기 때문에

그러니까 C++에서 new를 자바처럼 사용한다는건
C에서 모든 변수를 포인터로 선언해서 매번 malloc/free하는 것과 같은데
그런 독특한 취향을 가지고 있지 않는 이상
성능을 걱정할건 아니라고 봅니다

필요하니까 쓰는 것입니다
예를 들면 스마트포인터를 사용하지 않으면
예외가 발생할때 메모리누수가 생길 수 있으니
스마트포인터를 사용하여 방지한다거나 하는 경우

쩝의 이미지

코드 길이도 길어지고 결국은 파괴자에서 딸린 멤버 변수 해제만 정확히 해제 해주면 되지 않나 생각해 봅니다.
저는 클래스 사용 목적이 자동화 기능이라 해야하나? 생성자 파괴자를 많이 활용하는 편이고 다형성정도만 사용합니다.

특별한 패턴 같은건 사용하지 않내요.

특히 제가 가장 싫어 하는 것중에 하나가 가비지 컬렉터가 있는 언어들을 매우 싫어 합니다. 제 코딩 스탈이 그래서 그런가 봅니다.

아무튼 저는 c++11 또는 그 이상에서 맘에 안드는 것들 중 하나가 이게 라이브러리 업데이트인지 키워드 업데이트 인지 모르겠다는 겁니다.

표현식도 점점 엉망이 되어 가고 있는거 같구요.

slee0303의 이미지

스마트 포인터는 가비지 컬렉터가 아닙니다.

또한 현 버전의 C++은 semantics 면에서 많은 변화가 있어서 이전의 C++과는 다른 언어처럼 느껴지기도 한다고 합니다. 단순한 syntax에서만 바뀐 것이 아닙니다.

스마트 포인트 측면에서도, weak pointer 또는 shared pointer를 사용하여 메모리 누수를 방지하는 것이 거의 필수적인 경우가 많이 있습니다.

문제는 10년 넘게 C++ 했다고 말하는 사람들 중에도 스마트 포인터에 대한 개념 자체가 없는 경우가 많다는 거죠.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.