4

malloc と realloc を明確にするために、次のコードを作成しました。malloc を使用してポインターを初期化し、次に realloc を使用して、配列のサイズを増やしています。しかし、コードを実行すると次のエラーが発生します。

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

int main()
{
    char *p;
    p = malloc(10);
    p = " this is it";
    printf("\n%s", p);
    p = realloc(p, 14);
    p[11] = 'A';
    p[12] = 'B';
    p[13] = 'C';
    printf("\n %s", p) ;
    return 0;
}

出力:

ajay@ajay-K54L:~$ gcc te.c 
ajay@ajay-K54L:~$ ./a.out

*** glibc detected *** ./a.out: realloc(): invalid pointer: 0x000000000040071c ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7e626)[0x7fb111e88626]
/lib/x86_64-linux-gnu/libc.so.6(realloc+0x2de)[0x7fb111e8d3ee]
./a.out[0x4005dc]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7fb111e2b76d]
./a.out[0x4004d9]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:03 3027043                            /home/ajay/a.out
00600000-00601000 r--p 00000000 08:03 3027043                            /home/ajay/a.out
00601000-00602000 rw-p 00001000 08:03 3027043                            /home/ajay/a.out
00e76000-00e97000 rw-p 00000000 00:00 0                                  [heap]
7fb111bf4000-7fb111c09000 r-xp 00000000 08:03 2100801                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7fb111c09000-7fb111e08000 ---p 00015000 08:03 2100801                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7fb111e08000-7fb111e09000 r--p 00014000 08:03 2100801                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7fb111e09000-7fb111e0a000 rw-p 00015000 08:03 2100801                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7fb111e0a000-7fb111fbd000 r-xp 00000000 08:03 2100780                    /lib/x86_64-linux-gnu/libc-2.15.so
7fb111fbd000-7fb1121bc000 ---p 001b3000 08:03 2100780                    /lib/x86_64-linux-gnu/libc-2.15.so
7fb1121bc000-7fb1121c0000 r--p 001b2000 08:03 2100780                    /lib/x86_64-linux-gnu/libc-2.15.so
7fb1121c0000-7fb1121c2000 rw-p 001b6000 08:03 2100780                    /lib/x86_64-linux-gnu/libc-2.15.so
7fb1121c2000-7fb1121c7000 rw-p 00000000 00:00 0 
7fb1121c7000-7fb1121e9000 r-xp 00000000 08:03 2100760                    /lib/x86_64-linux-gnu/ld-2.15.so
7fb1123d2000-7fb1123d5000 rw-p 00000000 00:00 0 
7fb1123e5000-7fb1123e9000 rw-p 00000000 00:00 0 
7fb1123e9000-7fb1123ea000 r--p 00022000 08:03 2100760                    /lib/x86_64-linux-gnu/ld-2.15.so
7fb1123ea000-7fb1123ec000 rw-p 00023000 08:03 2100760                    /lib/x86_64-linux-gnu/ld-2.15.so
7ffff08d4000-7ffff08f5000 rw-p 00000000 00:00 0                          [stack]
7ffff09ff000-7ffff0a00000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
 this is itAborted (core dumped)

メモリ割り当てで何が間違っていますか? ありがとうございました。

4

3 に答える 3

8

これ:

p = " this is it"; /* Does not copy, use strcpy(). */

文字列リテラルのアドレスを に割り当て、p以前に によって返されたアドレスから変更しmalloc()ます。渡されるポインターは次のようにするrealloc()必要があります。

... 以前に malloc()、calloc() または realloc() によって割り当てられ、まだ free() で解放されていない場合、結果は未定義です。

strcpy()たとえば、割り当てを次のように変更して修正します。

p = malloc(12); /* Increased size. */
if (p)
{
    strcpy(p, " this is it");
    char* tmp = realloc(p, 14);  /* Store result in temp to avoid potential */
    if (!tmp)                    /* in the event that realloc() fails. */
    {
        free(p);
        return -1;
    }
    p = tmp;
    /* snip ... */

    free(p); /* When 'p' is no longer required. */
}
于 2013-02-26T13:42:31.907 に答える
3

によって返されたポインタmalloc()を文字列で上書きしています。

p = " this is it";

を使用して、 :strcpy()が指すメモリに文字列をコピーする必要があります。p

strcpy(p, "this is it");

ただし、上記の文字列には割り当てよりも多くのスペースが必要であることに注意してください。表示される10文字ですが、文字列のターミネータは0文字であるため、少なくとも11文字のスペースが必要です。

また、ポインタが有効であることに依存する前に、malloc()との両方の戻り値を確認する必要があります。realloc()の場合NULL、割り当ては失敗しました。割り当てサイズを考慮すると、これはあまりありそうにありませんが、良い習慣です。

于 2013-02-26T13:41:37.873 に答える
2
char *p = malloc(10);

サイズのメモリ ブロックを割り当て、このメモリ10pポイントします。それで

p = " this is it";

定数文字列リテラルを定義し、pこの定数文字列リテラルが格納される読み取り専用メモリを指定します。そう

p = realloc(p, 14);

未定義の動作reallocを生成するこの読み取り専用メモリを試行します。


定数文字列リテラルのアドレスを割り当てる代わりにp(動的に割り当てたメモリのアドレスが失われるため、メモリ リークも発生します)、 を使用してこの文字列をコピーする必要がありますstrcpy。したがって、次の行を置き換えます。

p = " this is it";

これとともに:

strcpy(p, " this is it");
于 2013-02-26T13:44:37.843 に答える