구조체 변수 메모리 할당오류 및 초기화 관련 질문
조회수 2935회
#include <stdio.h>
#include <stdlib.h>
#define SIZE_QUEUE 100 //the maximum size of the news_queue
#define CAPACITY 6 //the capacity of ZNN.com (per sec)
#define NUM_USER 20 //the number of users
#define NUM_LOOP 100 //the number of loops
//ContentFidelity is one of the types: video, image, text
typedef enum { Video, Image, Text } ContentFidelity;
typedef struct {
unsigned int requestedBy;
ContentFidelity fidelity;
} news; // 사용자 8이 동영상을 요청하면, 요청한 뉴스 콘텐츠를 (8,video)로 출력한다
typedef struct {
news queue[SIZE_QUEUE];
unsigned int front;
unsigned int rear;
} Queue; // 사용자가 요청한 뉴스 콘텐츠 쌓는 큐
Queue *news_queue;
ContentFidelity currentFidelity = Video; // 처음 콘텐츠는 동영상
/**/
typedef struct Person { // 사용자 구조체(콘텐츠 개수와 대기시간 정보)
int content_num; // 요청한 콘텐츠 전체개수
int receive_content; // 수신받은 콘텐츠 전체개수
int waiting_time; // 총 delay time
int content_score; // 수신받은 콘텐츠들의 총점수
}Person;
typedef struct PersonArray { // 사용자 구조체를 위한 구조체(배열)
Person people[NUM_USER];
int total_waiting_time; // 총 대기시간
int total_waiting_people; // 지금까지 콘텐츠를 요청한 사용자들의 수(중복 가능)
}PersonArray;
PersonArray *PeopleArray = (PersonArray*)malloc(sizeof(PeopleArray));
for (int i = 0; i < NUM_USER; i++) {
PeopleArray->people[i].content_num = 0;
PeopleArray->people[i].receive_content = 0;
PeopleArray->people[i].waiting_num = 0;
PeopleArray->people[i].content_score = 0;
}
/*PeopleArray초기화*/
int individual_count = 0; // 한 콘텐츠 받기까지의 개인당 대기시간을 측정하기 위한 변수
void request(Queue *news_queue, int count_start) { // count_start : enqueue한 시점
individual_count = count_start; // enqueue한 시점 저장
int request[20];
for (int i = 0; i < 20; i++) { // 20명이므로 20번 돌린다
int tf = rand() % 2; // true of false -> request 할지 말지
if (tf) {
news_queue->rear = (news_queue->rear + 1) % SIZE_QUEUE;
news_queue->queue[news_queue->rear].requestedBy = i;
news_queue->queue[news_queue->rear].fidelity = currentFidelity;
PeopleArray->total_waiting_people++; // 총 대기인수 +1
PeopleArray->people[i].content_num++; // i번 사람의 요청 콘텐츠 개수 +1
request[i] = i; // request한 사용자 번호 임시저장
}
}
printf(" >>>>Requesting(ENQUEUE):");
for (int j = 0; j < sizeof(request) / sizeof(request[0]); j++) {
printf(" %d,", request[j]);
}
printf("\n");
}
//enqueue 하고 count 시작 -> dequeue하고 count 끝. 총 대기시간을 person구조체에 넣어줘야 한다.
void setFidelity(Queue *news) {
float average_wait;
if (PeopleArray->total_waiting_people == 0)
average_wait = 0;
else
average_wait = PeopleArray->total_waiting_time / PeopleArray->total_waiting_people; // 평균 콘텐츠 대기 시간
if (average_wait >= 3) {
if (currentFidelity == Video)
currentFidelity = Image;
else if (currentFidelity == Image)
currentFidelity = Text;
else if (currentFidelity == Text)
currentFidelity = Text;
}
else if (average_wait <= 2) {
if (currentFidelity == Text)
currentFidelity = Image;
else if (currentFidelity == Image)
currentFidelity = Video;
else if (currentFidelity == Video)
currentFidelity = Video;
}
printf("Average waiting time: %f, Current Quality: %c\n", average_wait, currentFidelity);
}
void provide(Queue *news, int count_end) { // count_end : dequeue한 시점. request함수의 count_start에서 -count_end를 하면 개인당 대기시간이 나온다
int i = 0; // 1초당 제공 가능한 크기(최대 6)
int num; // 누구에게 콘텐츠 제공하는지 확인하기 위한 num
individual_count = count_end - individual_count; // dequeue한 시점 - enqueue한 시점 = 개인이 걸린 대기시간
printf("Providing(DEQUEUE) : ");
while (i <= 6 && news->front != news->rear) { // i가 6이 될 때까지, 큐가 빌 때까지 dequeue 한다
switch (news->queue[news->front].fidelity) {
case Video:
i = i + 3;
if (i > 6) // i가 6보다 크면 break;
break;
printf("(%d, %c), ", news->queue[news->front].requestedBy, news->queue[news->front].fidelity);
num = news->queue[news->front].requestedBy; // 현재 콘텐츠 제공 받은 사람의 번호 정보
PeopleArray->people[num].receive_content++; // num번 사람이 수신한 콘텐츠 개수 +1
PeopleArray->people[num].waiting_time += individual_count; // num번 사람이 대기한 총시간 +
PeopleArray->people[num].content_score += 3; // num번 사람의 콘텐츠 점수 +3
PeopleArray->total_waiting_time += PeopleArray->people[num].waiting_time; // 총 대기시간에 그만큼 +
news->front = (news->front + 1) % SIZE_QUEUE;
/*PeopleArray->total_waiting_people--; //대기인수 -1*/
break;
case Image:
i = i + 2;
if (i > 6) // i가 6보다 크면 break;
break;
printf("(%d, %c), ", news->queue[news->front].requestedBy, news->queue[news->front].fidelity);
num = news->queue[news->front].requestedBy; // 현재 콘텐츠 제공 받은 사람의 번호 저장
PeopleArray->people[num].receive_content++; // num번 사람이 수신한 콘텐츠 개수 +1
PeopleArray->people[num].waiting_time += individual_count; // num번 사람이 대기한 총시간 +
PeopleArray->people[num].content_score += 2; // num번 사람의 콘텐츠 점수 +2
PeopleArray->total_waiting_time += PeopleArray->people[num].waiting_time; // 총 대기시간에 그만큼 +
news->front = (news->front + 1) % SIZE_QUEUE;
/*PeopleArray->total_waiting_people--; //대기인수 -1*/
break;
case Text:
i = i + 1;
if (i > 6) // i가 6보다 크면 break;
break;
printf("(%d, %c), ", news->queue[news->front].requestedBy, news->queue[news->front].fidelity);
num = news->queue[news->front].requestedBy; // 현재 콘텐츠 제공 받은 사람의 번호 저장
PeopleArray->people[num].receive_content++; // num번 사람이 수신한 콘텐츠 개수 +1
PeopleArray->people[num].waiting_time += individual_count; // num번 사람이 대기한 총시간 +
PeopleArray->people[num].content_score += 1; // num번 사람의 콘텐츠 점수 +1
PeopleArray->total_waiting_time += PeopleArray->people[num].waiting_time; // 총 대기시간에 그만큼 +
news->front = (news->front + 1) % SIZE_QUEUE;
/*PeopleArray->total_waiting_people--; //대기인수 -1*/
break;
}
}
}
void printQueue(Queue *news) {
int i = news->front;
printf("In the queue: [");
do {
printf("(%d, %c), ", news->queue[i].requestedBy, news->queue[i].fidelity);
i = (i + 1) % SIZE_QUEUE;
} while (i != news->rear); // 큐의 rear까지 도달할 때까지 출력
printf("]\n");
}
void printResult() {
float average_time[20]; // 평균대기시간
for (int i = 0; i < 20; i++) {
average_time[i] = PeopleArray->people[i].waiting_time / PeopleArray->people[i].receive_content;
}
float average_score[20]; // 평균 콘텐츠 점수
for (int i = 0; i < 20; i++) {
average_score[i] = PeopleArray->people[i].content_score / PeopleArray->people[i].receive_content;
}
printf("******Result*****\n");
printf("User Avg.wait Avg.score\n");
for (int i = 0; i < 20; i++) {
printf("User%d: %fs %f", i, average_time[i], average_score[i]);
}
}
void main() {
unsigned int nthLoop;
for (nthLoop = 0; nthLoop < NUM_LOOP; nthLoop++) {
printf("\n=======%d seconds======\n", nthLoop);
//users can request contents every two loops
if (nthLoop % 2 == 0) {
setFidelity(news_queue);
request(news_queue, nthLoop);
}
printQueue(news_queue);
provide(news_queue, nthLoop);
}
printResult();
}
위는 전체 고드입니다. 제가 도저히 해결하지 못하는 부분은 아래 부분의 코드입니다.
#include <stdio.h>
#include <stdlib.h>
#define SIZE_QUEUE 100 //the maximum size of the news_queue
#define CAPACITY 6 //the capacity of ZNN.com (per sec)
#define NUM_USER 20 //the number of users
#define NUM_LOOP 100 //the number of loops
//ContentFidelity is one of the types: video, image, text
typedef enum { Video, Image, Text } ContentFidelity;
typedef struct {
unsigned int requestedBy;
ContentFidelity fidelity;
} news; // 사용자 8이 동영상을 요청하면, 요청한 뉴스 콘텐츠를 (8,video)로 출력한다
typedef struct {
news queue[SIZE_QUEUE];
unsigned int front;
unsigned int rear;
} Queue; // 사용자가 요청한 뉴스 콘텐츠 쌓는 큐
Queue *news_queue;
ContentFidelity currentFidelity = Video; // 처음 콘텐츠는 동영상
/**/
typedef struct Person { // 사용자 구조체(콘텐츠 개수와 대기시간 정보)
int content_num; // 요청한 콘텐츠 전체개수
int receive_content; // 수신받은 콘텐츠 전체개수
int waiting_time; // 총 delay time
int content_score; // 수신받은 콘텐츠들의 총점수
}Person;
typedef struct PersonArray { // 사용자 구조체를 위한 구조체(배열)
Person people[NUM_USER];
int total_waiting_time; // 총 대기시간
int total_waiting_people; // 지금까지 콘텐츠를 요청한 사용자들의 수(중복 가능)
}PersonArray;
PersonArray *PeopleArray = (PersonArray*)malloc(sizeof(PeopleArray));
for (int i = 0; i < NUM_USER; i++) {
PeopleArray->people[i].content_num = 0;
PeopleArray->people[i].receive_content = 0;
PeopleArray->people[i].waiting_num = 0;
PeopleArray->people[i].content_score = 0;
}
/*PeopleArray초기화*/
보시다시피 제가 원하는 것은 PersonArray의 포인터 구조체 PeopleArray에 메모리할당을 하여 초기화하는 것입니다.
하지만 위는 함수 밖에서 메모리 할당을 하는 거여서 그런지 malloc부분에 붉은 줄표시가 뜨면서 '상수식에 함수 호출을 사용할 수 없습니다' 라고 뜹니다.
PersonArray *PeopleArray = (PersonArray*)malloc(sizeof(PeopleArray));
이 문장을 아무 함수 안에서 적으면 malloc에 전혀 붉은줄이 뜨지 않습니다.
int num = sizeof(PersonArray);
PersonArray *PeopleArray = (PersonArray*)malloc(num);
PersonArray *PeopleArray = (PersonArray*)malloc(88);
도 마찬가지로 malloc에 붉은 줄이 뜨며 '상수식~' 의 문장이 뜨며 에러가 뜹니다.
PersonArray *ptrPeopleArray;
PersonArray l_personArray;
ptrPeopleArray = &l_personArray;
을 이용하려고 해도 초기화만 하려고 하면
l_personArray.total_content_num = 0;
에서 . 부분에 붉은줄이 표시되며 ';가 필요합니다' 라는 오류문구가 뜹니다....
현재 상황이 main함수를 변경하면 안되는 상황이기에 저는 PeopleArray의 메모리 할당, 초기화, PeopleArray안의 people배열을 반복문을 이용한 초기화하는 과정을 함수 밖, 전역부분에서 해결해야 하는 상황입니다.
(위 코드에서 for부분에서 '선언이 필요합니다' 라는오류가 뜹니다)
어떻게 해야 이 오류를 해결할 수 있을까요?
1 답변
-
전역부분에서는 malloc()을 비롯한 함수호출, for문, while문, if문 등이 사용불가합니다.
따라서 이 문제를 해결하기 위해서는 다음과 같이 init함수를 정의하여 해결하시면 될 것 같습니다.
/***************** 구조체 정의 (news, Queue 등) *****************/ int individual_count; // 한 콘텐츠 받기까지의 개인당 대기시간을 측정하기 위한 변수 PersonArray *PeopleArray; Queue *news_queue; ContentFidelity currentFidelity; void init(void) { individual_count = 0; currentFidelity = Video; // 처음 콘텐츠는 동영상 /*PeopleArray초기화*/ PeopleArray = (PersonArray*)malloc(sizeof(PersonArray)); for (int i = 0; i < NUM_USER; i++) { PeopleArray->people[i].content_num = 0; PeopleArray->people[i].receive_content = 0; PeopleArray->people[i].waiting_time = 0; PeopleArray->people[i].content_score = 0; } } /************************* 함수 정의 (request, setFidelity 등) *************************/ void main() { init(); //init함수를 제일 먼저 호출 unsigned int nthLoop; for (nthLoop = 0; nthLoop < NUM_LOOP; nthLoop++) { printf("\n=======%d seconds======\n", nthLoop); //users can request contents every two loops if (nthLoop % 2 == 0) { setFidelity(news_queue); request(news_queue, nthLoop); } printQueue(news_queue); provide(news_queue, nthLoop); } printResult(); }
-
(•́ ✖ •̀)
알 수 없는 사용자
-
댓글 입력