구조체의 메모리 할당에대해서요..

facered79의 이미지

struct temp{
     int i;
     char name[];
};
 
int main()
{
    struct temp s;
    s.i=1;
    name="1234"; //error 발생
                            //incompatible types in assignment of `const char[5]' to `char[0]'
 
    return 0;
}
 
 
[code]
 
위 코드에서 int 로 선언한 i 에 1을 대입할때는
 
오류가 생기지 않습니다.
 
name 에 "1234"를 대입하면 오류가 발생하고요..
 
둘다 메모리 할당을 하지 않고 대입을 하는데
 
왜 char 형만 오류가 발생하는것인가요..
 
그리고 메모리 할당의 필요성에대한 조언 해주시면 감사하겠습니다.[/code]
임종규의 이미지

facered79 wrote:

name="1234"; //error 발생
//incompatible types in assignment of `const char[5]' to `char[0]'

구조체 선언할때 에러가 나지 않는것이 이상하지만.. 일단...

name 은 char [] 즉 문자배열로 선언을 하셨습니다. 그리고 거기다가 "1234" 라는 문자열상수를 대입하려고 하셨죠....
문자배열의 원소 하나하나에는 문자상수가 대입되지만 문자열을 처리하는 직접적인 명령어는 c 에서 제공하지 않습니다.

string.h 이나 stdlib.h 에 있는 strcpy 라는 함수를 이용하시길 권합니다.

문자열 부분을 좀더 보셔야 할듯하군요

---------------------------------

메모리 할당의 필요성에 대한 덧글 추가요~

간단한 예로 노트패드와 같은 간단한 워드프로세서를 보시면 사용자가 어떠한 작업을 하든 그에 대한 대응을 하도록 즉 글자를 치면 글자를 입력받아 저장할수 있도록 모셔두죠. 그런데 그 사용자가 얼마나 입력을 할지 그 누구도 모르죠. 즉 확실하게 확보할 수 없는, 충분히 변화할 수 있는 내용의 경우에는 그 변화에 맞쳐서 프로그램이 다룰 수 있는 메모리의 양이 물리적으로 증가해야 됩니다. 문서를 열 때도 마찬가지죠. 작은 문서는 적은 메모리가 사용되겠지만 10메가가 넘고 그림이 첨가된 문서 많은 메모리가 사용되어야 겠죠. 변화하는 상황에 맞게 프로그램에게 변화할 수 있는 융통성을 부여하는 것이 메모리할당의 필요성이라고 생각됩니다.

/* How to Love Others */
while(GetDepth(Love) < Enough) DoLove();

욱성군의 이미지

포인터와 같은 메모리 관리 부분을 배우시려면 책을 하나 보시는 것이 좋아요 :)
정보 문화사의 '다시 체계적으로 배우는 C언어 포인터' 라는 책을 추천합니다. 되게 쉽고 간단하게 설명되어있답니다 :)

plodder의 이미지

연속되는 메모리 공간을 할당받기 위해 구조체에서 위와 같은 배열을 선언하기도 합니다.

위의 예제는 배열의 크기가 0이므로 sizeof해서 구조체의 크기를 확인해 보시면 아마도 4가 나올겁니다. name을 위한 메모리 공간은 없는거죠. --

struct temp *s = (struct temp*)malloc(sizeof(int) + sizeof(char) * 10)

혹은

struct temp *s = &some

같은 형식으로 이용하실 수 있습니다.

addnull의 이미지

char name[]을 메모리 할당을 하지 않고 fix로 잡을 때는

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

struct temp
{
	int	i;
	char	name[5];
};

int main()
{
	struct temp	s;
	s.i = 0;
	strcpy(s.name, "123");
	return 0;
}

이렇게 하시면 되구요.
메모리 할당을 하시려면,

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

struct temp
{
	int	i;
	char	*name;
};

int main()
{
	struct temp	s;
	s.i = 0;
	s.name = (char*)malloc(sizeof(char)*4);
	strcpy(s.name, "123");
	return 0;
}

이렇게 하시면 됩니다.
참고로 char 배열 선언 하실때

char a[];

이런 식으로 하시면 에러납니다.

char a[]="123"; 또는 char a[4];

이렇게 확실하게 배열의 크기를 알 수 있도록 해야합니다.

char *a;

하실때에는 변수를 사용하기 전에
필히 malloc 같은 함수로 메모리를 할당해줘야하구요 ^^

2005년 8월 4일.

lunarboy의 이미지

덧붙이자면,
배열의 이름은 첫번째의 요소의 주소에 대한 상수(!) 포인터입니다.
따라서 선언 당시 초기화 한 이 후에는 거기에 다른 주소값을 대입할 수 없습니다.
배열의 각 구성요소에 대한 값을 변경하는 것만이 가능하죠.

tinywolf의 이미지

c책의 포인터와 문자열 부분을 차분히 읽어보거나 주변의 뛰어난 사람이나 선생님께 물어보는 것이 좋은 방법일 것같습니다.. 왠지 글로 설명하기 어려운 내용이 되어 버린듯하군요.

ㅡ_ㅡ;

cppig1995의 이미지

임종규 wrote:
구조체 선언할때 에러가 나지 않는것이 이상하지만.. 일단...

C99 에서는 Flexible Array Member 가 가능합니다.
단, 구조체의 마지막 Member 에 한해서요.
오류가 나지 않는 것이 당연하지요.

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

xster의 이미지

배열은 선언할 때 문자열을 지정해주면 배열의 초기값을 지정하는 것이 됩니다.
배열의 이름은 값을 할당할 수 없는 상수의 포인터로 작동되어 읽을 수만 있습니다. 아래와 같이 나중에 배열 이름에 문자열 포인터를 지정하는 것은 오류가 되지요.

int main()
{
  char name1[] = "name1"; // 정상 초기값 설정이고 크기는 문자열의 크기를 따른다. 정상
  char name2[];
  name2 = "name2"; // 배열의 이름에 문자열 포인터값을 할당하려고 했다. 오류
  return 0;
}

좀 풀어서 쓰자면
char name1[] = "name1";
이 선언문의 의미는
char name1[] = {'n','a','m','e','1','\0'};
와 같은 의미가 됩니다.

Quote:
C99 에서는 Flexible Array Member 가 가능합니다.
단, 구조체의 마지막 Member 에 한해서요.
오류가 나지 않는 것이 당연하지요.

Flexible Array Member 가 가능하다는 게 무슨 의미인가요?
struct s {
  int i;
  char name[];
};

int main()
{
  struct s * temp_struct = malloc(sizeof(*temp_struct) + 10);
  printf ("%d\n", sizeof(temp_struct->name));
  return 0;
}

이렇게 하면 10이 나온다는 것인가요?
아니면 단순히 구조체 마지막 배열 요소의 크기만 안 정해져도 된다는 것인가요?
C99가 나왔지만 새로운 것에는 아직 익숙하지 않은 게 너무 많군요.

crimsoncream의 이미지

sizeof에 값이 반영되지는 않고 다만 structure 내의 변수명과 첨자로 가변 길이를 가진 data에 access 할 수 있다는 거 정도가 실천적 의미일 것 같은데요.

xster wrote:

Flexible Array Member 가 가능하다는 게 무슨 의미인가요?
struct s {
  int i;
  char name[];
};

int main()
{
  struct s * temp_struct = malloc(sizeof(*temp_struct) + 10);
  printf ("%d\n", sizeof(temp_struct->name));
  return 0;
}

이렇게 하면 10이 나온다는 것인가요?
아니면 단순히 구조체 마지막 배열 요소의 크기만 안 정해져도 된다는 것인가요?
C99가 나왔지만 새로운 것에는 아직 익숙하지 않은 게 너무 많군요.

오늘 우리는 동지를 땅에 묻었습니다. 그러나 땅은 이제 우리들의 것입니다.
아직도 우리의 적은 강합니다. 그러나 우리는 그들보다 많습니다.
항상 많을 것입니다.

lovewar의 이미지

Quote:

C99 에서는 Flexible Array Member 가 가능합니다.
단, 구조체의 마지막 Member 에 한해서요.
오류가 나지 않는 것이 당연하지요.

gcc 3.2.2, dev-c++ 4.9.8.1의 경우는 모두 컴파일이 되더군요.

단, 아래의 코드의 경우는
gcc 는 에러를, dev-c++는 컴파일을 하는군요.

struct record 
{ 
     char value[]; 
     int  key;
};

-- 덧붙이는 글 --
혹시 다른 컴파일러들은 어떤 반응을 보일지 궁금합니다.
다른 컴파일러를 가진 분들의 의견 부탁드립니다.

addnull의 이미지

lovewar wrote:
-- 덧붙이는 글 --
혹시 다른 컴파일러들은 어떤 반응을 보일지 궁금합니다.
다른 컴파일러를 가진 분들의 의견 부탁드립니다.

gcc에서 c99 지원은 3.0 이상부터 지원되더군요.
버전별로 지원되는 내용도 조금씩 다른 것 같습니다만,
저도 c99에 대해선 직접 찾아본 적이 없어서 자세한 내용은.. =_=a

cppig1995 wrote:
C99 에서는 Flexible Array Member 가 가능합니다.
단, 구조체의 마지막 Member 에 한해서요.
오류가 나지 않는 것이 당연하지요.

c99가 아직 대중적으로 퍼지지 않았기 때문에
저런 문법을 보면 우선 거부감부터 들더군요.
fiexible array member 허용 범위도 약간 다른가 봅니다.

Quote:
Flexible array members

C99 allows a flexible array member only at the end of a struct. GNU C allows it anywhere in the structure. C++ provides partial support by allowing zero-extent arrays.

2005년 8월 8일.

elien의 이미지

dev-c++ 은 컴파일러가 아닌 IDE 이며, Mingw/GCC 를 컴파일러로 사용하고 있습니다.

struct record
{
     char value[];
     int  key;
};

이 코드의 경우 gcc-linux-3.4.3 과 mingw-gcc-3.4.2, Visual C++ 6.0 모두 에러를 발생시키네요
제 생각엔 다른 컴파일러도 다를 것 같진 않습니다

훗, 못 믿겠나?

lovewar의 이미지

Quote:

dev-c++ 은 컴파일러가 아닌 IDE 이며, Mingw/GCC 를 컴파일러로 사용하고 있습니다.

확인해 보니 gcc version 3.2 (mingw special 20020817-1) 입니다.

elien님께 감사..

doldori의 이미지

xster wrote:
Flexible Array Member 가 가능하다는 게 무슨 의미인가요?
struct s {
  int i;
  char name[];
};

int main()
{
  struct s * temp_struct = malloc(sizeof(*temp_struct) + 10);
  printf ("%d\n", sizeof(temp_struct->name));
  return 0;
}

이렇게 하면 10이 나온다는 것인가요?
아니면 단순히 구조체 마지막 배열 요소의 크기만 안 정해져도 된다는 것인가요?


struct s는 크기에 관한 정보가 완전히 알려지지 않은 incomplete type입니다.
그리고 sizeof(*temp_struct)의 결과는 flexible array member를 제외한 크기가 됩니다.
그러나 sizeof(temp_struct->name)은 에러입니다. 컴파일 타임에 그 크기를
결정할 수 없으니까요.

댓글 달기

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