2

malloc で sizeof 演算子を使用すると問題が発生します。たとえば、以下を参照してください。コード-

#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;
}

ideone では、次のエラーが表示されます:- * glibc が検出されました./prog: free(): 次のサイズが無効です (高速): 0x09bcf008 * *

しかし、 malloc(sizeof(s)) を malloc(strlen(s)+1) に置き換えると、プログラムは完全に機能します。だから問題は何ですか?注:これは、私が別のコードで抱えていた問題を示すために作成した小さなプログラムです。

4

7 に答える 7

6

演算子sizeofは、ポインターに対して必要なことを行いません。マシン上のポインターのサイズが得られます (4 または 8 のようなものになります)。

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


また、ループが 0 ターミネータを埋めていないことにも注意してください。

于 2012-04-13T21:11:14.633 に答える
6

関数ではsizeofの代わりにstrlenを使用する必要があります。copy

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 -> そのポインタの格納に使用されるバイト) のサイズを返します。ドキュメントのリンクを確認して、より明確に理解してください。

もう 1 つ、C のスキルを練習するためにそうしている場合は問題ありませんが、そうでない場合は、おそらくstrcpy関数を使用したいと思うでしょう。

それが役に立てば幸い。

于 2012-04-13T21:11:30.920 に答える
4

サイズ情報を持つ配列と文字列は、関数にパラメーターとして渡されると、サイズ属性を失うポインターに縮退されます

したがって、パラメータのサイズを計算するとs、ビット数に基づいて 32/64 が返されます。

の代わりに、null 文字に対応するために実際に 1 つ追加するsizeof必要があります。strlen

それ以外の

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

試す

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

ご注意ください:

コードには他の設計上の問題があります

  1. 変更を想定していないポインター引数を渡す場合は、const として宣言する必要があります。

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

于 2012-04-13T21:12:00.840 に答える
4

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

于 2012-04-13T21:12:34.740 に答える
1

sizeofポインタのサイズ (通常は 4 または 8 バイト) を返します。ポイント先のオブジェクトのサイズではありません。(後者の情報を取得する方法はありません。ちなみに、 sizeof実質的にはコンパイル時の定数です。)

于 2012-04-13T21:12:57.183 に答える
1

sは char へのポインタであるため、charmalloc(sizeof(s))への 1 つのポインタにスペースを割り当てます。通常は 2 ~ 8 バイト、ほとんどの場合 4 バイトです。現状では、渡した文字列の長さに関係なく、常にこの固定量のスペースを割り当てます。テストでは、それよりもはるかに長い文字列を渡しているため、割り当てたバッファーをオーバーフローさせます。

あなたはすでに正しい答えを与えられています.状況下でstrlenは、サイズを見つけるための正しい関数です.

于 2012-04-13T21:14:13.910 に答える
0

malloc は で宣言されているため、malloc を呼び出すすべてのプログラムにそのヘッダーを #include します。C における「バイト」は、定義上、1 文字を格納するのに適したストレージの量であるため、上記の malloc の呼び出しにより、要求した数の文字が正確に得られます。結果のポインタは次のようになります。

于 2014-02-03T06:32:42.667 に答える