2012-04-13 10 views
2

ちょっと、mallocでsizeof演算子を使用する際に問題があります。たとえば、follを参照してください。 ideone上malloc(sizeof(s))は、予想より少ないメモリを割り当てますか?

#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
char * copy(char *s) 
{ 
    char *t=malloc(sizeof(s)); 
    char *ptr=s; 
    int i=0; 
    do 
    { 
     t[i++]=*ptr++; 
    } 
    while(*ptr!='\0'); 
    return t; 
} 
int main() 
{ 
    char *s="hello adsjahsjkdhjkashdkjaskdasldjlasjdlajsdlkjaslkdjalsjdlasjdljasdljasdkljklsdjlasdsadasdasd"; 
    char *b=copy(s); 
    printf("%s\n",b); 
    free(b); 
    return 0; 
} 

コード - 、それがエラーを与える: - :無料():無効次のサイズ(速い):0x09bcf008 * *

しかし *のglibcの ./progを検出私はmalloc(sizeof(s))をmalloc(strlen(s)+1)に置き換えて、プログラムは完璧に動作します。だから問題は何ですか? 注:これは私が別のコードで持っていた問題を示すために作成したちょっとしたプログラムです。

+0

もし 'malloc' *が*要求されたものより少ない(* none *を除いて' NULL'を返す場合を除いて)割り当てを行うと、実装にバグが見つかりました - - おめでとう! –

答えて

6

オペレーターsizeofは、ポインターではしません。それはあなたのマシン上のポインタのサイズをもたらします(4または8のようになります)。

このように考えることができます。配列は関数に渡されるときにポインタに減衰し、そのサイズに関する情報は "失われています"。


また、ループが0ターミネータに入力されないことに注意してください。

+0

@downvoterあなたは改善を提案できますか? – cnicutar

6

あなたはcopy機能にstrlen代わりのsizeofを使用する必要があります。

char * copy(char *s) 
{ 
    char *t=malloc(strlen(s) + 1); 
    char *ptr=s; 
    int i=0; 
    do 
    { 
     t[i++]=*ptr++; 
    } 
    while(*ptr!='\0'); 
    return t; 
} 

問題はsizeofはあなたが必要な値を返さない、その関数はchar *s(おそらく4または8のサイズを返すということです - >そのポインタを格納するために使用されるバイト)。より明確に理解するために、ドキュメンテーションのリンクを確認してください。

あなたのCスキルを練習するためにそれをしているのならもう1つのことはOKですが、そうでない場合は、strcpy機能を使用したいと思う可能性があります。

希望します。サイズ情報と

+2

まだ十分ではありません... 'strlen'はヌルターミネータを数えません。 – dmckee

+0

あなたは正しく編集されています。ありがとう@dmckee! –

+0

2 @downvoters、改善を提案してください....なぜこの質問にはまだ回答が選択されていませんか? –

4

配列と文字列は、その大きさを失うのポインタに縮退ますあなたは、パラメータsの大きさを計算しているとき、それが機能

にパラメータとして渡されたときに属性だから、ベースの32/64を返すのいずれかあなたのビットで。

の代わりにstrlenを実際に実行して、ヌル文字を格納するために1を追加する必要があります。

代わり

char *t=malloc(sizeof(s)); 

char *t=malloc(strlen(s)+1); 

は注意してください試してみてください。

  1. があるポインタ引数を渡すあなたのコードと他の設計上の問題があります。 suでないあなたがそれをconstと宣言する必要があります。

  2. 一般的に、ローカルで生成されたヒープストレージのアドレスを返すのは良い方法ではなく、メモリを解放することを忘れるとメモリリークの大きな原因になります。代わりに、非constパラメータとして関数に渡します。

+0

匿名Downvoter明確化 – Abhijit

4

sizeof(s)システム(64ビットの場合)4であるchar *sのサイズ(32ビットの場合)または8を返します。

1

sizeofは、ポインティングされたオブジェクトのサイズではなく、ポインタのサイズ(通常は4または8バイト)を返します。典型的には、2 - (。。後者の情報に取得する方法はありませんsizeofを介して、効果的にコンパイル時定数である)

1

sのでmalloc(sizeof(s))がcharへの一つのポインタのためのスペースを割り当て、charへのポインタであります-8バイト、最も頻繁には4バイト。それは、あなたが渡した文字列の長さにかかわらず、この固定量のスペースを常に割り当てます。テストでは、それよりずっと長い文字列を渡しているので、割り当てたバッファがオーバーフローします。

あなたはすでに正しい答えが与えられています:状況によっては、strlenがサイズを見つける正しい関数です。

0

mallocが宣言されているので、mallocを呼び出すすべてのプログラムでそのヘッダをインクルードします。 Cの `` byte ''は定義上、一つの文字を格納するのに適した記憶量なので、上記のmallocの呼び出しは私たちが求める文字数と同じくらい多くの文字を返します。

+0

のように:???私はあなたがそこにいくつかのコードを配置することを忘れたと思う。 –

関連する問題