2013-08-04 18 views
5

IはCヘッダのmallocエラー(C)

typedef struct { 
    kiss_fft_scalar r; 
    kiss_fft_scalar i; 
} kiss_fft_cpx; 

に次のコードを持っており、私はテストプログラム

kiss_fft_cpx *fin = malloc(4*sizeof(kiss_fft_cpx)); 

に次のコードを実装し、それは私にエラーメッセージを与え: "型voidの値は、型 'kiss_fft_ctx'"の実体を初期化するためには使用できません。

私はVisual Studio C/C++のwin32コンソールプロジェクトを使用しています。

ここで正しくmallocを使用する方法を教えてもらえますか?ありがとう!

kiss_fft_cpx *fin = (kiss_fft_cpx*) malloc(4*sizeof(kiss_fft_cpx)); 

が、意味するところは、それはC++のエラーではなく、Cのエラーですので、あなたが、C++ではなくCのように、あなたのコードをコンパイルしているということです。

+0

[無効\ 'から'ノード\ * '\ [-fpermissive \]]への無効な複製(http://stackoverflow.com/questions/16793587/invalid-conversion-from-void-to -node-fpermissive) –

+1

エラーメッセージが 'voidを使用してkiss_fft_ctxを初期化することはできませんでした。私はそれが 'void *'と 'kss_fft_ctx *'だと思います。これらのアスタリスクは、言語の意味と理解に大きな違いをもたらします。 – abelenky

答えて

12

あなたはこのように戻り値の型をキャストする必要があります。ファイル拡張子やコンパイラの設定を確認することができます。 C++を使用して

あなたが本当にがある場合、あなたは最小限の使用newはなくmallocにする必要があります理想的

kiss_fft_cpx *fin = new kiss_fft_cpx[4]; 

、あなたはこのように動的にオブジェクトを作成する必要があるかどうかを考え直す - あなたが使用することができstd::vectorまたは類似の代わりに?

+2

+1はC++に関する注釈です。 –

+0

クールな問題は、私のC++プロジェクトで他人がプログラムしたCコードを使用する必要があることです。だから、メモリ割り当てを終了するためにmallocではなく他のスキームを使用することも可能かどうか疑問に思っています(そうでなければ、C++でCを使用するとC++がかなり愚かなように見えます) – Cancan

+4

@Cancan代わりにCとしてコンパイルしてください。 ** C++をC++としてコンパイルしようとしないでください。**異なる言語です。 –

3

Cでは、mallocが返すvoidポインターをキャストできます。 Cはこれを行いますが、明示的にすることもできます。

mallocは、void *またはvoidポインタを返します。この戻り値は、プログラマによって他のポインタ型にキャストできます。あるいは、プログラマはCを使って型変換を行うことができます。キャストを使用したCの型変換は変更されません。

ただし、Cコンパイラに依存するCコードは妨げになり、読みにくい場合があります。 開発プログラマーは、最終的にコードを読む必要があるメンテナンスプログラマーを助けることができます。

返された値mallocに明示的なキャストを追加すると、 を持つ人間は、コードを読み、作成者の意図を判断するのに役立ちます。これは、mallocによって返されたvoidポインタを明示的にキャストすることの本当の利点です。このプログラミングプラクティスは、コンパイラを間違って指示したり、変更されるかもしれないいくつかの難解なコンパイラ機能を使用したりしません。

次の3つの例は、このプログラミングの実践を強調しています。最初の例では、 malloc(これは<stdlib.h>で定義されています)が明示的にキャストされ、いくつかの簡単な作業が です。

#include <stdlib.h> 
    #define nr_chars 4 
    main() 
    { 
    char *data; 

    data = (char *) malloc(nr_chars*sizeof(char)); 

    *data++ = 'a'; 
    *data++ = 'b'; 
    *data++ = 'c'; 
    *data++ = '\0'; // it is allowed to go one past an array 

    data -= nr_chars; // back to the front of data 

    printf("%s\n", data); 
    // prints abc at the console 

    } 

この2番目の例では、唯一の違いは<stdlib.h>がコメントアウトされていることです。 コードが実行され、同じ結果が生成されます。さて、なぜこの作品が「なぜ」の理由はかなり直接的です。 Cが関数のプロトタイプを見つけられない場合、関数はintを返しますが、mallocはvoidポインタを返します。この場合、明示的キャストは、ソースの炭素単位と同様にCコンパイラに、mallocによって返された値を文字ポインタに変換する必要があることを伝えました。

//#include <stdlib.h> 
    #define nr_chars 4 
    main() 
    { 
    char *data; 

    data = (char *) malloc(nr_chars*sizeof(char)); 

    *data++ = 'a'; 
    *data++ = 'b'; 
    *data++ = 'c'; 
    *data++ = '\0'; // it is allowed to go one past an array 

    data -= nr_chars; // back to the front of data 

    printf("%s\n", data); 
    // prints abc at the console 

    } 

最終(うん)の例では、キャストを発行しないと<stdlib.h>が含まれていません。 Eclipseエディタとコンパイラの両方でこのコードについて不平を言います。コンパイラメッセージは

..\main.c(18) : warning C4047: '=' : 'char *' differs in levels of indirection from 'int' 

され、ソースコードは、次のとおり

//#include <stdlib.h> 
    #define nr_chars 4 
    main() 
    { 
    char *data; 

    data = malloc(nr_chars*sizeof(char)); 

    *data++ = 'a'; 
    *data++ = 'b'; 
    *data++ = 'c'; 
    *data++ = '\0'; // it is allowed to go one past an array 

    data -= nr_chars; // back to the front of data 

    printf("%s\n", data); 
    // compiler displays a "warning" and prints abc at the console 

    } 

変更例3は、警告なしで結果を含むことを目的とするように、プログラムが実行されます。しかし、例2と3の両方とも明示的なキャストがなく、この形式で書かれたコードの生涯にわたり、このようなコードは、より高価であり、人間によって間違って変更される可能性が高い(したがって、追加の費用) Cコンパイラ。