auto_ptr 질문.

hyperhidrosis의 이미지

auto_ptr 을 char* 에 대해서 써보기 위해서
이런 코드를 작성했는데

#include <stdio.h>
#include <string.h>
#include <memory>

using namespace std;
int main()
{
	auto_ptr<char> str (new char(20));
	strcpy(str, "hello");
	printf("%s\n", str);

	return 0;
}

Quote:
error C2664: 'strcpy' : cannot convert parameter 1 from 'class std::auto_ptr<char>' to 'char *'
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

이런 에러가 발생하는군요.. 어떻게 코드를 수정해야 할까요?

cppig1995의 이미지

1. auto_ptr 은 암시적 형변환을 지원하지 않습니다.
즉, auto_ptr<char> 가 자동으로 char * 이 되지 않습니다.
따라서 벙어리 (dumb) 포인터 즉, built-in 포인터를 얻는
Member Function (method?) 를 써야 합니다. 명시적으로.

inline T* auto_ptr<T>::get() const throw(); 'get' method 를 쓰시면 될 것입니다.

strcpy(str, "hello");

대신

strcpy(str.get(), "hello");

이렇게.

2. stdio.h, stdlib.h?

stdio.h 와 stdlib.h 는 C++ 표준 (C 표준이 아님) 에서
곧 사라질 포함 파일들입니다.
cstdio, cstdlib 란 이름을 애용하세요.
C++ 프로그래머시라면 말이죠.
stdio.h, stdlib.h 에서는 전역 공간에 정의되지만,
cstdio, cstdlib 에서는 std 이름 공간에 이름들이 정의됩니다.

3. 이런 용도라면 차라리 STL string 을 애용합시다.

#include <iostream>
#include <string>

using namespace std;

int main()
{
    string s;
    s = "hello";
    cout << s << endl;
    return 0;
}

C++ 표준, STL 의 string 클래스가 좋은 선택입니다.

string 의 정체 즉,

template <typename charT, typename traits = char_traits<charT>, typename alloc = allocator<charT> >
class basic_string;

typedef basic_string<char> string;

이런 지옥같은 선언을 외우는 센스가 필요합니다.
iostream 선언도 비슷하답니다.

Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.

doldori의 이미지

곁다리로 한 가지만 지적하면
new char(20)
이것은 1바이트를 할당한 후 20으로 초기화하는 것입니다. 코드의 의도로 보아
20바이트를 할당하려는 것 같은데, 그러려면 new char[20]과 같은 배열형의
new를 써야 합니다. 그러나 auto_ptr은 배열형의 new를 쓸 수 없습니다.
따라서 지금은 auto_ptr을 쓰면 안되는 경우가 되겠습니다.

쌀밥의 이미지

cout 이 C++ 스러워서 흥미가 가기는 하지만

stream 방식이 갖는 한계도 있다고 생각합니다.

string 을 처음 사용할때 printf 에 어떻게 넣는지 해메던 기억이 나서
별거 아니지만 적어봅니다.

string s;
s = "hello";
printf("%s\n", s.c_str());

일하는 사람들의 희망 민주노동당 : http://www.kdlp.org
반공 교육의 성과로, 민주주의의 반대가 공산주의(또는 사회주의)라고 생각하는 사람이 많다.

Kroisse의 이미지

쌀밥 wrote:
cout 이 C++ 스러워서 흥미가 가기는 하지만

stream 방식이 갖는 한계도 있다고 생각합니다.

string 을 처음 사용할때 printf 에 어떻게 넣는지 해메던 기억이 나서
별거 아니지만 적어봅니다.

string s;
s = "hello";
printf("%s\n", s.c_str());

offtopic이지만, printf도 stream방식이었던 거 아니었어요? ㅇㅅㅇ;

hyperhidrosis의 이미지

#include <cstring>
#include <memory>
#include <cstdio>

using namespace std;
int main()
{
   auto_ptr<char> str (new char[20]);
   strcpy(str.get(), "hello");
   printf("%s\n", str.get());
   return 0;
} 

여러분들의 조언으로 이런 코드를 사용하니 잘 돌아가는군요.
(설마 문제가 있는건 아니겠죠?)

new char[20] 와 new char(20) 을 구분못하는 제실력이 한심하군요..

doldori의 이미지

hyperhidrosis wrote:
여러분들의 조언으로 이런 코드를 사용하니 잘 돌아가는군요.
(설마 문제가 있는건 아니겠죠?)

문제 있습니다. 위에서 말했듯이 배열형의 new는 auto_ptr에 쓸 수 없습니다.
cppig1995의 이미지

hyperhidrosis wrote:
(설마 문제가 있는건 아니겠죠?)

doldori 님 말씀을 듣고 제대로 태클 걸어드리겠습니다.

auto_ptr 은 소멸자에서 delete [] 가 아닌 delete 로 개체를 삭제합니다.

new [] 로 할당된 공간을 delete 로 삭제하면,
결과는 Undefined Behavior 인 것으로 알고 있습니다.

boost::shared_array 를 사용하십시오.

http://boost.org

Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.

cppig1995의 이미지

Kroisse wrote:
offtopic이지만, printf도 stream방식이었던 거 아니었어요? ㅇㅅㅇ;

iostream 라이브러리를 지칭하신 듯.

사실, iostream 에선 이런 문제조차도 없습니다.

std::string s("Hello");
std::cout << s << std::endl;

그러고 보니 Koenig 검색이 왜 좋은지 알게 되네요.
cout 가 std 에 있으므로
알아서 ::operator << 찾지 않고
std::operator << 을 찾아준다는...
만약 Koenig 검색이 아니라면

std::string s("Hello");
std::cout.operator<<(s).operator<<(std::endl);

참고로

std::string s = "Hello";

대신

std::string s("Hello");

을 사용한 것은 Exceptional C++ (Herb Sutter, 2001) 에서
나온 바와 같이, 첫째 식보다 둘째 식이 효율이 좋기 때문입니다.
첫째 식은 다음과 같은 효과를 불러옵니다.

std::string s = std::string("Hello");

임시 객체 하나가 더 소모된다는 것이죠.

Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.

charsyam의 이미지

고정크기라면 string 보다도
vector 쪽이 좋아보입니다. ^^,

보통은 배열을 auto_ptr 형태로 써야 할 경우
vector 로 커버가능하지 않나요?

=========================
CharSyam ^^ --- 고운 하루
=========================

doldori의 이미지

돼지군 wrote:
만약 Koenig 검색이 아니라면

std::string s("Hello");
std::cout.operator<<(s).operator<<(std::endl);


실은
std::operator<<(std::cout, s).operator<<(std::endl);
를 호출하죠. :-)

댓글 달기

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