구조체 내에서의 메모리할당..
      글쓴이: yangam / 작성시간: 토, 2004/09/25 - 12:06오후    
  
  /*
최대 10 명까지의 학생에 대한 이번 학기에 수강하는 과목 및 성적
(중간고사,기말고사,수시고사,출결)을 입력 받아서 각 과목에 대한
평균점수와 이에 해당하는 학점(A+,A,B+,B,C+,C,D,F)을 계산하고
이에 대한 평점(최종성적) 및 석차를 구해서 석차순으로 학생들의
리스트를 출력하는 프로그램을 작성하라.
전제: 0. 학생들의 과는 모두 같다.
      1. 각 과목을 입력받을 때, 각 과목에 대한 학점도 함께 입력받는다.
      2. 입력받을 수 있는 과목의 수는 5개 - 8개로 제한.
      3. 출결은 16번을 만점으로 한다. 
      4. 중간고사, 기말고사, 수시고사는 100점을 만점으로 한다. 
*/
#include <stdio.h>
#include <stdlib.h>
// 상수 LEN 은 임시로 사용되는 문자형 배열의 길이
#define	LEN	64
typedef struct grade {
	char *student_name;		// 학생의 이름
	char **subject_name;		// 과목 이름을 저장
	int num_of_subject;		// 과목수를 저장
	int *credit;
} S;
int how_many_data_enter(char *temp);
void remove_newline_character(char *temp);
void enter_student_name(char *temp, S *pstudent, int num_of_student);
void enter_subject_name_and_credit(char *temp, S *pstudent, int index);
int main()
{
	char temp[LEN];
	int num_of_student;
	int i;
 	S *student;
	
	// 몇 명의 학생에 대한 성적을 입력할지를 결정한다.
	// (구조체 포인터의 동적할당에 대한 기초자료로 활용됨)
	num_of_student = how_many_data_enter(temp);	
	// 메모리 할당
	// S 구조체가 num_of_student 의 값만큼 생성됨
	student = (S *)malloc(sizeof(S) * num_of_student);
	// 학생의 이름을 입력받음
	enter_student_name(temp, student, num_of_student);
	// 입력받은 학생 이름 출력
	puts("\n------------------------------------------");
	puts("다음 학생들에 대한 데이터를 입력받겠습니다");
	puts("------------------------------------------\n");
	for (i = 0; i < num_of_student; i++)
		printf("%2d 번째 학생 : %s\n", i + 1, student[i].student_name);
	
	// 학생의 전공, 과목이름 및 학점, 시험성적, 출결을 입력받음
	for (i = 0; i < num_of_student; i++)
	{
		puts("\n-----------------------------------");
		printf("-> %s 학생에 대한 데이터 입력 <-\n", student[i].student_name);
		puts("-----------------------------------\n");
		// 과목 및 학점을 입력받음
		enter_subject_name_and_credit(temp, student, i);
	}
	// 학생 이름을 저장하는 배열에 설정된 메모리 해제
	for (i = 0; i < num_of_student; i++)
		free(student[i].student_name);
	// 구조체 포인터에 설정된 메모리 해제
	free(student);
	return 0;
}
// 입력받을 데이터의 학생의 수를 입력받는다. 
int how_many_data_enter(char *temp)
{
	int num_of_student;
	while (1)
	{
		printf("\n몇 명의 학생에 대한 성적을 입력 하실건가요..? (최대 10명): ");
		fgets(temp, LEN, stdin);
		num_of_student = atoi(temp);
		if (num_of_student >= 1 && num_of_student <= 10)
		{
			puts("\n-------------------------------------------");
			printf("%d 명의 학생들에 대한 성적을 입력받겠습니다.\n", num_of_student);
			puts("-------------------------------------------\n");
			return num_of_student;
		}
		else
		{
			printf("\n입력 가능한 값의 범위는 1 - 10명 입니다.\n");
		}
	}	
}
// remove newline character
void remove_newline_character(char *temp)
{
	int j = 0;
	while (1)
	{
		if (temp[j] == '\n')
		{
			temp[j] = '\0';
			break;
		}
			j++;
	}
}
void enter_student_name(char *temp, S *pstudent, int num_of_student)
{
	int i;
	for (i = 0; i < num_of_student; i++)
	{
		printf("%2d 번째 학생의 이름을 입력하세요: ", i + 1);
		fgets(temp, LEN, stdin);
		// '\n' 을 제거
		remove_newline_character(temp);
		
		// 학생의 이름을 ragged char array 로 저장(메모리 할당)
		pstudent[i].student_name = malloc(strlen(temp) + 1);
		// 학생의 이름을 저장함
		strcpy(pstudent[i].student_name, temp);
	}
}
void enter_subject_name_and_credit(char *temp, S *pstudent, int index)
{
	int i;
	// 신청한 과목의 수를 입력받음
	while (1)
	{
		printf("몇 개의 과목을 신청하셨나요..? (최소 5개, 최대 8개): ");
		fgets(temp, LEN, stdin);
		pstudent[index].num_of_subject = atoi(temp);
		if (pstudent[index].num_of_subject >= 5 && pstudent[index].num_of_subject <= 8)
		{
			// 학생의 과목수에 대한 메모리 할당
			pstudent[index].subject_name = (char **)malloc(pstudent[index].num_of_subject);
			puts("\n----------------------------------");
			printf("%d 개의 과목을 신청하셨습니다.\n", pstudent[index].num_of_subject);
			puts("----------------------------------\n");
			break;
		}
		else
		{
			puts("\n-------------------------------------");
			puts("입력 가능한 값의 범위는 5 - 8 입니다.");
			puts("-------------------------------------\n");
		}
	}
	for (i = 0; i < pstudent[index].num_of_subject; i++)
	{
		printf("%d 번째 과목의 이름을 입력하세요: ", i + 1);
		fgets(temp, LEN, stdin);
		// remove newline character
		remove_newline_character(temp);
		// dynamic memory allocation
		pstudent[index].subject_name[i] = (char *)malloc(strlen(temp) + 1);
		// 문자열 복사
		strcpy(pstudent[index].subject_name[i], temp);
	}	
	for (i = 0; i < pstudent[index].num_of_subject; i++)
	{
		printf("(for문밖)%s\n", pstudent[index].subject_name[i]);
	}
}
enter_subject_name_and_credit() 때문에 그러는데요;;
메모리 할당을 저렇게 하면 안되는건가요?
char **t; t = (char **)malloc(3); t[0] = (char *)malloc(2); t[1] = (char *)malloc(2); t[2] = (char *)malloc(2);
이렇게 해서 사용할 때는 잘되던데..
구조체에 들어가니 잘 안되네요;;
어떤점이 잘못됐는지 지적좀 해주세요..
참고로 간단한 설명을 하자면...
과목 수를 입력받고, 과목이름을 입력받는데요.
과목 수가 유동적이여서 우선 과목수만큼의 포인터 배열을 할당합니다.
그 다음에 과목 이름을 입력받는데요.
과목 이름의 길이만큼의 메모리를 각각의 포인터 배열에 할당하려는 것이
목표입니다.
1 byte 도 버리지 않고 메모리를 사용하고 싶어서요.
답변 부탁드립니다...
참고로 다른 소스파일을 열어서 이렇게 하니까 제대로 되네요;;
#include <stdio.h>
#include <stdlib.h>
#define LEN	70
// 프로그램을 위한 구조체 필드 선언
typedef struct grade {
	char **subject;		// 학생이 신청한 과목명
} S;
int main()
{
	// 학생 구조체 정의
	S *student;
	student = (S *)malloc(sizeof(S) * 2);
	student[0].subject = malloc(3);
	student[1].subject = malloc(3);
	student[0].subject[0] = malloc(2);
	student[0].subject[1] = malloc(4);
	student[0].subject[2] = malloc(5);
	student[1].subject[0] = malloc(2);
	student[1].subject[1] = malloc(4);
	student[1].subject[2] = malloc(5);
	strcpy(student[1].subject[0], "o");
	strcpy(student[1].subject[1], "ih!");
	strcpy(student[1].subject[2], "www!");
	strcpy(student[0].subject[0], "h");
	strcpy(student[0].subject[1], "hi!");
	strcpy(student[0].subject[2], "wow!");
	printf("%s\n%s\n%s\n", student[0].subject[0], student[0].subject[1], student[0].subject[2]);
	printf("%s\n%s\n%s\n", student[1].subject[0], student[1].subject[1], student[1].subject[2]);
}
Forums: 


[code:1]char **stringArray;stringA
char **stringArray; stringArray = (char**)malloc(sizeof(char*) * num); int i; for (i = 0; i < num; ++i) { stringArray[i] = (char*)malloc(sizeof(char) * (len+1)); }char*의 크기는 1이 아닙니다.
게으름은 이제 그만
감사합니다~
그렇게 사용해야 되는거였네요.. ㅎ_ㅎ
감사합니다
작은 것들, 사소한 것들을 소중히 여기고,
항상 최선을 다하는 멋진 사람이 되고 싶다.
그들이 나에게 일깨워준 것처럼,
그들 자신이 얼마나 소중한 존재인지 알 수 있도록
도와주는 그런 좋은 사람이 되고 싶다
구조체 메모리의 최소할당 크기는 4입니다.malloc(2) 이건 좀
구조체 메모리의 최소할당 크기는 4입니다.
malloc(2) 이건 좀 이상한 코딩이 되는거죠..
그냥 malloc(sizeof(blah~)*개수) 이렇게 하시는것이....
typedef stucture tagA { char a; } CA
하시면 sizeof(CA)는 4가 됩니다.
typedef structure tagB { char a1; int a2; char a3; int a4; } CB typedef structure tagC { char a1; char a3; int a2; int a4; } CC이렇게하면 CB는 16바이트가 되고,
CC는 12바이트가 됩니다.
포인터는 char* short* int* CA* 모두 4바이트입니다.(64bit머신 이상에서는 몰라염 -,-;; )
댓글 달기