리눅스 시스템 프로그래밍을 공부하고 있는데요. struct 내에 배열 선언시 int score[0]; 처럼 할 수가 있더군요 도와주세요

ljh665577의 이미지

#include
#include

typedef struct
{
  int count;
  char name[20];
  int score[0];
} FLEX;

int main(void)
{
  int i, j;
  FLEX *p = (FLEX *)malloc(4096);

  for(i=0; i     p->score[i] = i + 1;

  for(j=0; j     printf("p->score[%d] = %d\n", j, p->score[j]);

  return 0;
}


결과

p->score[0] = 1
p->score[1] = 2
p->score[2] = 3
p->score[3] = 4
p->score[4] = 5
.
.
.
p->score[95] = 96
p->score[96] = 97
p->score[97] = 98
p->score[98] = 99
p->score[99] = 100

와 같이 나오는데 배열선언을 int score[0]; 로 했는데 어떻게 이게 가능한지 이해가 잘 안갑니다.
도와주세요ㅜㅜ

shint의 이미지

- 크기는 0 입니다.
- 주소가 있으니. 사용은 가능합니다.
- 문제는 주소와 값이. 다른 변수등에 의해서 바뀌게 되거나. 다른 메모리를 사용하게 되는 경우 입니다.

이렇게 문자열을 사용하기도 합니다.

	char * pp = "TEST";
	printf("char * pp = \"TEST\";\n");
	printf("pp           %x\n", pp);
	printf("sizeof(p)  %d\n", sizeof(pp));
	printf("\n");
 
#if 0
char * pp = "TEST";
pp               489000
sizeof(pp)    4
#endif

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
 
 
typedef struct
{
	int count;
	char name[20];
	int score[0];
} FLEX;
 
#define TEST 10
 
int main(int argc, char** argv)
{
	int i, j;
 
	printf("#define TEST 10\n");
	printf("%x\n", TEST);
	printf("\n");
 
	const int TMP = 30;
	printf("%x\n", TMP);
	printf("%x\n", &TMP);
	printf("\n");
 
	int score[0];
	printf("int score[0];\n");
	printf("sizeof(score)       %d\n", sizeof(score));
	printf("sizeof(&score[0])   %d\n", sizeof(&score[0]));
	printf("&score[0]           %x\n", &score[0]);
	printf("\n");
 
	int score1[1];
	printf("int score1[1];\n");
	printf("sizeof(score1)      %d\n", sizeof(score1));
	printf("sizeof(&score1[0])  %d\n", sizeof(&score1[0]));
	printf("&score1[0]          %x\n", &score1[0]);
	printf("\n");
 
	int score2[2];
	printf("int score2[2];\n");
	printf("sizeof(score2)      %d\n", sizeof(score2));
	printf("sizeof(&score2[0])  %d\n", sizeof(&score2[0]));
	printf("&score2[0]          %x\n", &score2[0]);
	printf("\n");
 
	char ccore[0];
	printf("char ccore[0];\n");
	printf("sizeof(ccore)       %d\n", sizeof(ccore));
	printf("sizeof(&ccore[0])   %d\n", sizeof(&ccore[0]));
	printf("&ccore[0]           %x\n", &ccore[0]);
	printf("\n");
 
	char ccore1[1];
	printf("char ccore1[1];\n");
	printf("sizeof(ccore1)      %d\n", sizeof(ccore1));
	printf("sizeof(&ccore1[0])  %d\n", sizeof(&ccore1[0]));
	printf("&ccore1[0]          %x\n", &ccore1[0]);
	printf("\n");
 
	FLEX *p = (FLEX *)malloc( sizeof(FLEX) );
 
	printf("FLEX *p = (FLEX *)malloc( sizeof(FLEX) );\n");
	printf("_msize(p)          %d\n", _msize(p));
	printf("sizeof(p->name)    %d\n", sizeof(p->name));
	printf("sizeof(p->score)   %d\n", sizeof(p->score));
	printf("\n");
 
//--------------------------------
//할당안된 주소를 사용
//	for(i=0; i<5; i++)
//		p->score[i] = i + 1;
 
//	for(j=0; j<5; j++)
//		printf("p->score[ %d] = %d   %x\n", j, p->score[j], p->score[j]);
//--------------------------------
 
	free(p);
 
	return 0;
}
 
#if 0
 
#define TEST 10
a
 
1e
22fee8
 
int score[0];
sizeof(score)       0
sizeof(&score[0])   4
&score[0]           22fee8
 
int score1[1];
sizeof(score1)      4
sizeof(&score1[0])  4
&score1[0]          22fee4
 
int score2[2];
sizeof(score2)      8
sizeof(&score2[0])  4
&score2[0]          22fedc
 
char ccore[0];
sizeof(ccore)       0
sizeof(&ccore[0])   4
&ccore[0]           22fedc
 
char ccore1[1];
sizeof(ccore1)      1
sizeof(&ccore1[0])  4
&ccore1[0]          22fedb
 
FLEX *p = (FLEX *)malloc( sizeof(FLEX) );
_msize(p)          24
sizeof(p->name)    20
sizeof(p->score)   0
 
 
--------------------------------
Process exited after 0.6057 seconds with return value 0
계속하려면 아무 키나 누르십시오 . . .
 
#endif 

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

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

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

익명 사용자의 이미지

아랫분이 쓴 것처럼 용도를 자세히 모르는 상태에서 답글을 달면 선무당이 사람 잡는 것 이상도 이하도 아닙니다. 네, 당연히 선언을 저렇게 했으니 크기는 0이죠.

ljh665577의 이미지

네~참고하겠습니다

행복한 하루되세요!

익명 사용자의 이미지

ljh665577의 이미지

네 참고하겠습니다~

행복한 하루되세요!

twinwings의 이미지

C에서 사용하는 관용구(idiom)로서 struct hack 이라고 합니다.

이걸 사용하는 이유는 가변길이 데이터를 쉽게 다룰 수 있기 때문입니다.

예전에는 배열의 크기가 0인걸 허용하지 않아서 1로 했지만 최근 대부분의 C컴파일러들은

struct hack을 사실상 언어 표준으로 인정하고 있어서

struct hack {
    struct hack_hdr hdr;
    char data[0];
};

과 같은 표현이 가능 합니다.

주의할 점은 struct hack으로 선언된 구조체로 직접 메모리 할당을 하면 안됩니다.

보통 char로 버퍼를 할당 받은 후 캐스팅 해서 사용합니다.

char buffer[1024];
struct hack* h = (struct hack*)(buffer);

만약 직접 구조체를 이용해서 메모리를 할당 받으려고 하면 컴파일러가

"imcomplete type" 경고를 띄웁니다.
(C++에서 순수 가상 클래스를 이용해서 객체를 생성할 경우와 비슷하다고 보시면 됩니다.)

요약하자면

1. struct hack이라고 불리는 관용구(혹은 기법)으로서 가변길이 데이터를 쉽게 다르기 위함

2. 해당 구조체를 이용해서 직접 메모리 할당 받으면 안된다. 캐스팅해서 써야 한다.

PS.
배열을 [0]으로 선언했는데 메모리 침범 경고 및 런타임 에러가 발생하지 않는 이유는 2) 와 관련있습니다. 또한 기본적으로 C의 배열은 메모리 경계 체크를 하지 않는것도 한 몫 하구요.

twinwings의 이미지

생각해보니 괜히 글을 길게 적었네요.

KLDP 내에서도 struct hack 관련된 내용이 많습니다.

해당 키워드로 검색되는 다른 글들도 읽어보시길 바랍니다.

익명 사용자의 이미지

C99에서 flexible array member라는 이름으로 정식으로 편입되었고,
이땐 [0]이 아니라 []으로 씁니다.
구조체의 맨 마지막 맴버 변수에만 허용되는 형태입니다.

그런데 문제는, C++엔 아직 이것이 들어가 있지 않습니다.
자신이 현재 사용하는 컴파일러의 메뉴얼을 확인해 봐야 할 부분입니다.

jick의 이미지

Flexible array member는 C++의 클래스 상속과 충돌하기 때문에 앞으로도 C++에서 지원하지 않을 것 같습니다.

(C++ 쓰면서 가끔씩 아쉬울 때가 있더군요.)

ljh665577의 이미지

아직 완벽히 이해가 되지는 않았지만

덕분에 조금 갈피가 잡히네요 감사합니다

행복한 하루되세요!

댓글 달기

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