2015-11-17 3 views
0

Я пытаюсь создать ADT, первую очередь, здесь основная информация о нем:C- АТД, который держит сбой

typedef struct orange_t* Orange; 

typedef enum { 
JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC, 
} Month; 

struct orange_t { 

short size; 
Month expirationMonth; 
char** foodCompanies; 
int maxNumberOfFoodCompanies; 
int sellingPrice; 
}; 

теперь им пытаются создать функцию, которая будет «создать "новый оранжевый так:

Orange orangeCreate(short size,Month expirationMonth 
    ,int maxNumberOfFoodCompanies,int sellingPrice) 
{ 
    Orange new_orange=(Orange)malloc(sizeof(struct orange_t)); 
    if(new_orange==NULL) 
    { 
     return NULL; 
    } 
    if((sellingPrice<0)||(size>256||size<1)||(maxNumberOfFoodCompanies<0)||(expirationMonth>12) 
     ||(expirationMonth<1)) 
     { 
     return NULL; 
     } 
new_orange->sellingPrice=sellingPrice; 
new_orange->maxNumberOfFoodCompanies=maxNumberOfFoodCompanies; 
new_orange->expirationMonth=expirationMonth; 
new_orange->size=size; 
for(int i=0;i<new_orange->maxNumberOfFoodCompanies;i++) 
{ 
    new_orange->foodCompanies[i]=NULL; 
} 
return new_orange; 
} 

, когда я попытался проверить функцию с простым main():

int main() 
{ 
Orange orange=orangeCreate(3,JAN,10,4); 
printf("the size is %d\n",orange->size); 
orangeDestroy(orange); 
return 0; 
} 

программа продолжает сбой, я думаю, что я не изменил значения в оранжевом, как должен, и они все равно могут быть NULL. Где я здесь ошибся?

+1

Вы не выделяя 'foodCompanies' в любом месте, но при попытке индексировать и назначить его , –

+0

в C, возвращаемое значение из 'malloc()' и семейство функций - это тип 'void *', который может быть назначен любому другому указателю. Внедрение возвращаемого типа совершенно необязательно и приводит к трудностям при отладке и/или поддержании кода. Имя typedef 'Orange' вводит в заблуждение, так как оно фактически является типом указателя. Гораздо лучше typedef - это просто «struct orange_t» без указателя, а затем добавьте «*» по мере необходимости в теле кода. – user3629249

+0

перечисление начинается с 0 (если специально не определено иначе), поэтому проверка на 'expirationMonth' неверна, если только перечисление не изменено, поэтому первая запись:' JAN = 1, ' – user3629249

ответ

1

JAN is 0. if expirationMonth<1 Вы возвращаетесь NULL от orangeCreate.

Также: вы не проверяете возвращаемое значение orangeCreate. И вы теряете память в orangeCreate, когда вы только что вернетесь NULL без free входящих в выделенный new_orange.

1

Проблема заключается в том, что вы не выделять память для char** foodCompanies;


Хотя выделения памяти здесь

Orange new_orange=malloc(sizeof(struct orange_t)); 

Вы выделили место для переменнуюуказателя char** foodCompanies;, но не выделили места, где он будет указывать на.

1

Перед обращением к нему вы должны выделить некоторую память и сохранить ее адрес new_orange->foodCompanies.

Возможные исправления:

Orange orangeCreate(short size,Month expirationMonth 
    ,int maxNumberOfFoodCompanies,int sellingPrice) 
{ 
    Orange new_orange=malloc(sizeof(struct orange_t)); 
    if(new_orange==NULL) 
    { 
     return NULL; 
    } 
    if((sellingPrice<0)||(size>256||size<1)||(maxNumberOfFoodCompanies<0)||(expirationMonth>12) 
     ||(expirationMonth<1)) 
     { 
     return NULL; 
     } 
new_orange->sellingPrice=sellingPrice; 
new_orange->maxNumberOfFoodCompanies=maxNumberOfFoodCompanies; 
new_orange->expirationMonth=expirationMonth; 
new_orange->size=size; 
new_orange->foodCompanies=malloc(sizeof(char*)*new_orange->maxNumberOfFoodCompanies); /* add this line */ 
for(int i=0;i<new_orange->maxNumberOfFoodCompanies;i++) 
{ 
    new_orange->foodCompanies[i]=NULL; 
} 
return new_orange; 
} 

Примечание: это не рекомендуется, чтобы бросить результат malloc() в С.
c - Do I cast the result of malloc? - Stack Overflow

Смежные вопросы