2013-04-12 2 views
0

У меня есть следующий код, в котором, когда я пытаюсь освободить память malloc'ed, я иногда получаю ошибку сегментации. Эта ошибка возникает только при освобождении памяти, связанной с некоторыми из моих членов структуры (только по прозвищу и за ее пределами), что означает, что я никогда не получаю ошибку сегментации для free(player->name), но примерно в половине случаев я получаю ошибки сегментации от двух других разрядов (видя, как инструменты является нулевым, это не имеет никакого эффекта)Случайная ошибка сегментации на указателях malloc'd

typedef struct player_t { 
    char * name; 
    char * nickname; 
    Instrument * instruments; 
    int instrumentAmount; 
} * Player; 

Player playerCreate(const char* name, const char* nickname, 
int maxInstruments) { 
    Player one=malloc(sizeof(Player)); 
    if(one==NULL || !checkLegalName(name)|| !checkLegalName(nickname) || maxInstruments<=0) { 
     return NULL; 
    } 

    one->name=malloc(strlen(name)+1); 
    one->nickname=malloc(strlen(name)+1); 

    if(!one->name || !one->nickname) { 
     playerDestroy(one); 
     return NULL; 
    } 

    strcpy(one->name,name); 
    strcpy(one->nickname,nickname); 
    one->instrumentAmount=maxInstruments; 
    one->instruments=NULL; 
    return one; 
} 

следует этим:

void playerDestroy(Player player) { 
    if(!player) { 
     return; 
    } 

    free(player->name); 
    free(player->nickname); // this is where it happens. 
    free(player->instruments); 
    free(player); 
} 

Любой помощь в решении этого будет оценена.

+0

Скорее всего, вы будете вне границ некоторого массива, записывая в течение некоторого адреса и получить ошибку, когда вы освободив. Вы должны попробовать отладки и, возможно, еще более удобный запуск 'valgrind', чтобы увидеть, что происходит не так и где. – Shahbaz

ответ

2

Ваша (Main-) проблема в этой строке:

Player one=malloc(sizeof(Player)); 

игрок определяется как указатель на player_t структуру, и поэтому вы не оставляя достаточно памяти, чтобы сохранить всю структуру. Этого достаточно только для первого указателя (name), поэтому вы видите сбой при доступе к nickname.

Try:

Player one=malloc(sizeof(struct player_t)); 
+0

Nice catch! (+1) – nneonneo

+0

Спасибо, что решил. – Thongurf

+1

Вот почему многие люди не любят типы указателей, скрытые внутри typedef, и используют идиому 'toto * x = malloc (sizeof * x)' для выделения пространства. –

1
one->nickname=malloc(strlen(name)+1); 
... 
strcpy(one->nickname,nickname); 

Что делать, если nickname больше, чем name?

+0

Спасибо, что заметили, исправили его :) – Thongurf