2015-06-26 5 views
2

Я просматриваю C и используя splint для проверки исходного кода.Утечка памяти после использования свободной() в функции эсминца в c (в соответствии с шиной)

Я пытаюсь сделать следующее:

  • создать структуру с помощью функции «конструктора»
  • разрушают структуру с функцией «деструкторов», который освобождает память структуры.

Однако, когда я тестирую свой код с шиной, он выдает предупреждения, связанные с временным хранилищем в деструкторе, и утечку памяти после вызова деструктора.

Мне интересно (а), правильна ли шина относительно утечки памяти в моем коде (я думаю, что это не так), и (б) что я должен сделать, либо исправить мой код, либо сделать шину понять, что я делаю ,

Во всяком случае, вот код:

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

// define the structure 
struct Boring { 
    int amount; 
}; 

// the creator 
static struct Boring *Boring_create(int amount) { 
    struct Boring *really = malloc(sizeof(struct Boring)); 
    assert(really != NULL); 
    really->amount=amount; 
    return really; 
} 

// the destroyer 
static void Boring_destroy(struct Boring *really) { 
    assert(really != NULL); 
    // free the memory of the Boring structure 
    free(really); 
} 

int main(/*@[email protected]*/ int argc, /*@[email protected]*/ char *argv[]) { 
    int amount = 5; 
    struct Boring *tv = Boring_create(amount); 
    printf("The TV is boring level %d\n",tv->amount); 

    // destroy the tv! 
    Boring_destroy(tv); 

    printf("The TV is now boring level %d\n",tv->amount); 
    return 0; 
} 
/* Output */ 
/* 
* $> ./destroytv 
* The TV is boring level 5 
* The TV is now boring level -538976289 (or 0 depending on OS/compiler) 
*/ 

Код компилируется и работает нормально с НКУ.

Однако, когда я использую щепу, чтобы проверить его, лубок выдает следующие предупреждения:

$> splint boringtv.c 
destroytv.c: (in function Boring_destroy)  
destroytv.c: Implicitly temp storage really passed as only param: free (really) 
Temp storage (associated with a formal parameter) is transferred to a new non-temporary reference. The storage may be released or new aliases crated. (Use -temptrans to inhibit warning) 
destroytv.c: (in function main) 
destroytv.c: Fresh storage tv not released before return 
A memory leak has been detcted. Storage allocated locally is not released before the last reference to it is lost (use -mustfreefresh to inhibit warning) 
Fresh storage tv created 

Первое предупреждение, тем больше я думаю об этом, тем меньше я понимаю. Но я недостаточно читал руководства, чтобы оправдать правильный вопрос об этом.

Второе предупреждение, касающееся утечки памяти, кажется, что шина просто не осознает, что память освобождается в другом месте, что кажется мне странным. Предупреждение уходит, если я просто позвоню free() в пределах main.

Заранее благодарим за помощь. Пожалуйста, дайте мне знать, будет ли полезно более подробная информация, например, номера строк для предупреждений.

+3

"Во всяком случае, здесь суть кода" - делает "GIST" код размещен здесь вы также можете опубликовать фактический обмен сообщениями? И вы знаете, что вы вызываете неопределенное поведение с помощью 'printf (« Теперь телевизор скучный уровень% d \ n », tv-> amount)', правильно? – WhozCraig

+0

Правильный термин - деструктор, а не разрушитель –

+0

Код скопирован, сообщение скорректировано с учетом того же кода, минус номера строки. извините за путаницу, я удалил gist. Я не знал, что это неопределенное поведение. – hilcharge

ответ

3

Не существует утечки памяти, как подозревали.

Чтобы сообщить splint, какая функция должна иметь контроль над памятью структуры, входной сигнал функции деструктора должен быть аннотирован /*@[email protected]*/.

static void Boring_destroy(/*@[email protected]*/ struct Boring *really) {... 

Это говорит splint, что эта функция принимает единоличное управление переменной, что позволяет ему освободить память спокойно, не поднимая никаких предупреждений.

В частности, единственная аннотация означает, что [s] ссылка является единственным указателем на объект, на который указывает. ' (руководство по шине)

Аннотации удаляют оба предупреждения, упомянутые в исходном вопросе, и заменяют их предупреждением, указывающим, что tv используется после его уничтожения. Это новое предупреждение желательно, потому что, как упоминалось в комментариях WhozCraig, вызов памяти после его освобождения является неопределенным поведением и, следовательно, его следует избегать.

Ссылки: