1

文字列を格納するためにメモリを動的に割り当てる必要がある私のコードは次のとおりです。

#define _XOPEN_SOURCE 700

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

int main()
{
    char **path = NULL;

    path = (char **) malloc(sizeof(char *));

    for (int i = 0; i < 5; i++)
    {
            path[i] = strdup("TEST");
            path = (char **) realloc(path, sizeof(char *));
    }

    for (int i = 0; i < 5; i++)
    {
            printf("%s\n", path[i]);
    }

    return 0;
}

上記のコードは、メモリを再割り当てした行で中断します。

私によると、最初の malloc でパスに割り当てられたメモリは次のとおりです。

path -----> |   char *  | // path points to a character pointer which       inturn is pointing to nothing(Dangling).

したがって、この時点で、プログラムは次の行を実行しました。

path = (char **) malloc(sizeof(char *));

path[0] は現在境界内にあり、path[0] に 1 つだけの文字列の開始アドレスを格納でき、この時点で path[1] は境界外になるはずです。

そのため、path[i] に文字列のアドレスを保存している for ループに初めて入ったとき、次のようにできます。

path[0] = strdup("TEST"); // is in bounds.

別の文字列を保存するには、パスが指しているはずのメモリがさらに必要です。だから私は次のようにすぐ下の行で再割り当てを行いました:

path = (char **) realloc(path, (char *));

したがって、私によると、パスは次のようにメモリ内で次のようになります。

path --------->|old char *|----->"TEST"
  |----------->|new char *|----->(Dangling) // Pointing Nowhere.

したがって、path[1] も範囲内にあり、そのメモリ ロケーションを使用できるはずです。したがって、コードを実行すると、このセグメンテーション違反が発生する理由がわかりません。

*** glibc detected *** ./dynamic: realloc(): invalid next size: 0x0000000000602010 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x75018)[0x7f743153e018]
/lib64/libc.so.6(+0x7ae96)[0x7f7431543e96]
/lib64/libc.so.6(realloc+0xfa)[0x7f74315441aa]
./dynamic[0x40067f]
/lib64/libc.so.6(__libc_start_main+0xe6)[0x7f74314e7bc6]
./dynamic[0x400569]
======= Memory map: ========
00400000-00401000 r-xp 00000000 00:27 14459340                           /home/xpansat/c/basic/dynamic
00600000-00601000 r--p 00000000 00:27 14459340                           /home/xpansat/c/basic/dynamic
00601000-00602000 rw-p 00001000 00:27 14459340                           /home/xpansat/c/basic/dynamic
00602000-00623000 rw-p 00000000 00:00 0                                  [heap]
7f742c000000-7f742c021000 rw-p 00000000 00:00 0 
7f742c021000-7f7430000000 ---p 00000000 00:00 0 
7f74312b2000-7f74312c8000 r-xp 00000000 fd:01 173                        /lib64/libgcc_s.so.1
7f74312c8000-7f74314c7000 ---p 00016000 fd:01 173                        /lib64/libgcc_s.so.1
7f74314c7000-7f74314c8000 r--p 00015000 fd:01 173                        /lib64/libgcc_s.so.1
7f74314c8000-7f74314c9000 rw-p 00016000 fd:01 173                        /lib64/libgcc_s.so.1
7f74314c9000-7f743161d000 r-xp 00000000 fd:01 27                         /lib64/libc-2.11.1.so
7f743161d000-7f743181d000 ---p 00154000 fd:01 27                         /lib64/libc-2.11.1.so
7f743181d000-7f7431821000 r--p 00154000 fd:01 27                         /lib64/libc-2.11.1.so
7f7431821000-7f7431822000 rw-p 00158000 fd:01 27                         /lib64/libc-2.11.1.so
7f7431822000-7f7431827000 rw-p 00000000 00:00 0 
7f7431827000-7f7431846000 r-xp 00000000 fd:01 20                         /lib64/ld-2.11.1.so
7f7431a14000-7f7431a17000 rw-p 00000000 00:00 0 
7f7431a44000-7f7431a45000 rw-p 00000000 00:00 0 
7f7431a45000-7f7431a46000 r--p 0001e000 fd:01 20                         /lib64/ld-2.11.1.so
7f7431a46000-7f7431a47000 rw-p 0001f000 fd:01 20                         /lib64/ld-2.11.1.so
7f7431a47000-7f7431a48000 rw-p 00000000 00:00 0 
7fff62f8c000-7fff62fa2000 rw-p 00000000 00:00 0                          [stack]
7fff62fff000-7fff63000000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

以下のように realloc 行を変更するとコードを実行できたので、何が間違っているのかわかりません。

path = (char **) realloc(sizeof(char *)*8);

その乗算を 8 で実行した場合、私のコードは実行されますが、必要な正確なメモリを割り当てたいのですが、8 を乗算しないと動作しない理由はありますか?

4

2 に答える 2