2010-11-30 11 views
3

gcc 4.4.4 c89callocを使用してメモリを割り当てて解放する

私はテストしているプログラムを持っています。私はdevnameという構造体オブジェクトを作成し、要素を埋めることができるようにメモリを割り当てます。私はそれらを表示し、割り当てられたメモリを解放します。

invalid operands to binary != (have ‘struct Devices_names’ and ‘void *’) 

構造要素を表示するためのループのための私である:

しかし、私は、次のエラーを取得しています。しかし、私はNULLポインタをテストしていると感じています。

ちょっと質問がありますが、無料で問題がありますか?あなたが唯一の全体devname配列を作成する一つの割り当てを持っているので、どんなアドバイスを

多くのおかげで、

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

static struct Devices_names { 
#define MAX_NAME_LEN 80 
    int id; 
    char name[MAX_NAME_LEN]; 
} *devname; 

static void g_create_device_names(size_t devices); 
static void g_get_device_names(); 
static void destroy_devices(); 

int main(void) 
{ 
#define DEVICES 5 
    g_create_device_names(DEVICES); 

    g_get_device_names(); 

    destroy_devices(); 

    return 0; 
} 

static void g_create_device_names(size_t devices) 
{ 
    size_t i = 0; 
    devname = calloc(devices, sizeof *devname); 
    if(devname == NULL) { 
     exit(0); 
    } 

    for(i = 0; i < devices; i++) { 
     devname[i].id = i; 
     sprintf(devname[i].name, "device: %d", i); 
    } 
} 

static void g_get_device_names() 
{ 
    size_t i = 0; 

    for(i = 0; devname[i] != NULL; i++) { <-- ERROR HERE 
     printf("Device id --- [ %d ]\n", devname[i].id); 
     printf("Device name - [ %s ]\n", devname[i].name); 
    } 
} 

static void destroy_devices() 
{ 
    while(devname != NULL) { 
     free(devname++); 
    } 
} 

答えて

4

は、あなただけのNULLのためにその配列を確認する必要がある、とだけその1つの配列を解放する必要があります。 devnameを見ると、各エントリは実際にはポインタではなくstruct Devices_namesであるため、NULLと比較することも、意味のある方法で解放することもできません。この場合は、あなたがそこにあるどのように多くのエントリ追跡する別の変数が必要になります。

for (i = 0; i < devname_count; i++) { 
    printf("Device id --- [ %d ]\n", devname[i].id); 
    printf("Device name - [ %s ]\n", devname[i].name); 
} 

... 

free(devname); 
devname = NULL; 
devname_count = 0; 
+0

私は以下のdevnameを=はcalloc(デバイス、sizeof演算子*のDEVNAME)を行ったとき。私はヒープ上に5つのdevnameオブジェクトを作成していると思った。だから私はそれらの5つすべてを解放しなければならないだろう。しかし、割り当てられたオブジェクトは1つしかないと言っていますか?ありがとう。 – ant2009

+1

5つのオブジェクトに対して* space *を作成していますが、実際には1つの連続したチャンクしか割り当てていません。経験則として、 'malloc()'または 'calloc()'の各呼び出しは、 'free()'を1回呼び出すだけで一致しなければなりません。 –

+0

ありがとう、私はそれを覚えています。簡単なルールのように聞こえる。 – ant2009

2

devname[i]はそのstruct Devices_namesポインタではありませんが、そのため比較は意味がありません。あなたが書く

1

for(i = 0; devname[i] != NULL; i++) { <-- ERROR HERE 

あなたはNULLに対してDevice_namesのインスタンスではなく、ポインタをテストしています。 Device_namesへのポインタの配列があれば問題ありません。

もう1つの問題は、Device_namesを1つだけ割り当てているため、それらの配列がないことです。

1

callocの後には、返されたポインタがヌルでないことをテストする必要があります(そして、calloc呼び出しが成功しました)。第二は、コンパイルされますaltough

しかし、あなたはcallocは、配列をated一度もないdevname[i] != NULLので、それへのポインタのみを持つどのように多くの項目配分のあなたが判断することはできません、またdevname+i != NULLは、動作しません。環境やRTLだけがこれを知っています。これは*alloc割り当てと静的宣言の大きな違いです(C99で導入された可変サイズのものでも)。だからあなたは割り当てられた配列のサイズを他の場所に格納する必要があります。

calloc()で割り当てられた配列(または他のメモリチャンク)も、free()の呼び出しで、mallocから返されるSAMEポインタを使用して割り当て解除する必要があります。他のポインタをfree()に渡すと、未定義の動作が発生します(これはしばしばFAILです)。

だからあなたのコードは次のようになります。

static struct Devices_names { 
#define MAX_NAME_LEN 80 
    int id; 
    char name[MAX_NAME_LEN]; 
} *devname; 
size_t devicecount; 

... 

    devname = calloc(devices, sizeof *devname); 
    if(devname == NULL) { 
     exit(0); 
    } 
    devicecount = devices; 

... 

    for(i = 0; i<devicecount; i++) { // <-- no error more here 

... 

static void destroy_devices() 
{ 
    free(devname); 
} 
関連する問題