[C++]구조체 내부의 크기가 1인 배열

wafe의 이미지

struct Sta
{
    ...
    int array[1];
};

이런 구조체를 사용할 때는 malloc을 써서 struct Sta * 형으로 동적으로 만들어 주어야 하나요?

Sta *a = (Sta *a)malloc(sizeof Sta + 배열크기);

이렇게 말이지요. new로는 불가능할 것 같은데... C++에서 malloc을 쓰자니 왠지 꺼림칙합니다.

그리고 이런 배열을 뭐라고 불러야 하는 건가요? "가변 길이 배열"하고는 좀 다른 것 같아서요.

girneter의 이미지

구조체 내부에서
크기가 1인 배열이라기 보다는
가변길이의 배열을 쓰고 싶으신거죠

그럼
array 를 pointer 로 선언하시고

Sta 의 생성자에서

array = new int [size];

라고 하시면 될텐데요
소멸자에서 delete [] 하시는거 잊지 마시고.

그리고

Sta* p = new Sta(10);

이런 식으로 하면 되지 않을까요?
굳이 크기 1인 배열을 쓰셔야 하나요?

개념없는 초딩들은 좋은 말로 할때 DC나 웃대가서 놀아라. 응?

cinsk의 이미지

그런 형태를 쓰는 방식을 지정하는 정확한 용어는 없습니다만 대개 "struct hack"이라고 부르기도 합니다. 새로운 C 표준인 C99에서는 flexible array member라는 것을 도입해서 위 문제를 쉽게 해결할 수 있도록 도와줍니다.

http://www.cinsk.org/cfaqs/html/node13.html

에서 11.11 section을 참고하기 바랍니다.

wafe의 이미지

girneter wrote:
구조체 내부에서
크기가 1인 배열이라기 보다는
가변길이의 배열을 쓰고 싶으신거죠

굳이 크기 1인 배열을 쓰셔야 하나요?

네 가변길이 배열을 쓰고 싶습니다.

제가 새로 만드려고 하는 것은 아니고 만들어진 라이브러리를 쓰고있기 때문입니다. Win32 GDI에도 저런 구조체가 참 많더군요. :(

포인터를 쓰는게 더 좋은데 말이에요. ^^

Heejoon Lee

hanzo69의 이미지

그런 가변길이 클래스를 new로 할당받고 싶으시다면..

// 배열의 길이가 가변적인 템플릿 선언
template < class T, int _buf_siz_ > class VarBufFmt {
public
int m_iTop;
T m_varBuf[ _buf_siz_ ];
};

// char형 10개짜리 배열을 가지는 클래스형 포인터 선언
VarBufFmt <char, 10> *pBuf10;

// char형 10개짜리 배열을 가지는 클래스형 객체 할당
pBuf10 = new VarBufFmt <char, 10>;

님ㅎ 즐~

doldori의 이미지

C의 API와 맞춰야 한다면 별로 뾰족한 수는 없겠군요. 다만 wrapping 클래스를
만들어 좀 편하게 쓸 수는 있겠습니다. 소멸, 복사, 대입도 적절히 만드시고요.

class Wrapper
{
public:
	Wrapper(int size)
		: p(static_cast<Sta*>(malloc(sizeof(*p) + sizeof(p->array[0]) * (size - 1))))
	{
		if (!p) throw std::runtime_error("");
	}
	operator Sta*() { return p; }
private:
	Sta* p;
};
swellee의 이미지

질문을 제대로 이해 했는지 모르지만 보통 이렇게 많이 씁니다.

char *tmp = (char*)malloc(sizeof(struct Sta) + sizeof(int)*(sz-1));
                                           // sizeof(배열타입)*(배열크기 - 1)
struct Sta *sta = (struct Sta*) tmp;

...그런데 질문한 지 많이 지나서

체스맨의 이미지

wafe wrote:

포인터를 쓰는게 더 좋은데 말이에요. ^^

포인터를 쓰는게 더 좋다고 볼 수는 없습니다.
두번 할당할 것을 한번에 할당하면 조금이라도 메모리는 적게 듭니다.해제할때도 더 편하구요. 또한 멤버에 접근하는데 배열 멤버인 경우 포인터 참조가 한번이면 됩니다. 포인터 멤버였다면 두번 참조해야 되겠죠.

이 기법은 C 에서 자주사용되고, 유용한 기법이며, C++ 클래스와new로는 할 수 없는 방법입니다. 위에서 템플릿으로 예제를 주셨지만 배열 크기나 타입에 따라 각기 다른 클래스가 되기 때문에 동일한 기법들을 적용할 수 없습니다.

위에서 C99 표준을 말씀해 주셨고, GNU C 에서는 구조체 내에 0
길이 배열을 지원하기도 합니다.

struct _my_struct {
    ...;
    char name[0];
};

Orion Project : http://orionids.org

댓글 달기

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