-1

2D配列を使用したプログラムがあります。まず、次のように配列を割り当てます。

char **crossword;
crossword = (char **) malloc(n* sizeof(*crossword));
for (i = 0; i < n; i++)
    crossword[i] = (char *)malloc(n);

ここで、n = 50 です。

次に、標準入力から文字列を読み取る関数があります。問題は、これらの文字列がいくつになるか、またはどれくらいの長さになるかわからないことです。

void read(char **p,int *n)
{
char tmp = 0,prevtmp = 0;
int i = 0, j = 0,x;

while (1)
{
    prevtmp = tmp;
    tmp = getchar();
    if ((tmp == '\n' && prevtmp == '\n') || feof (stdin))
    {
        *n = i;
        break;
    }
    if (tmp == '\n')
    {
        p[i][j] = '\0';
        i++;
        if (i == *n)
        {
            p = (char **) realloc(p, 2*i); // if there is more strings than space for them, allocate more memory.
            for (x = i; x < 2*i; x++)
                p[x] = (char *) malloc (*n);

            *n *= 2;
        }
        j = 0;
        continue;
    }
    p[i][j] = tmp;
    j++;
    if (j == *n)
        p[i] = (char *)realloc(p[i], 2*j); //same as above
}
}

関数は次のように呼び出されます。

read(crossword,&n);

この関数は、realloc が必要ない場合 (それぞれが 50 文字未満の文字列が 50 未満の場合) に正常に機能します。しかし、大きな入力の場合、これは失敗します

*** glibc detected *** ./a.out: malloc(): memory corruption (fast): 0x00000000014282f0 *** error.

私の問題は、より多くのメモリを再割り当てする部分にあると思います.valgrindからの出力は次のとおりです。

==8885== Invalid write of size 1
==8885==    at 0x40084C: read (in /home/xerw/Dropbox/CVUT/PROGTEST/du6/a.out)
==8885==    by 0x40177F: main (in /home/xerw/Dropbox/CVUT/PROGTEST/du6/a.out)
==8885==  Address 0x51f2b88 is not stack'd, malloc'd or (recently) free'd
==8885== 
==8885== Invalid write of size 8
==8885==    at 0x4008A6: read (in /home/xerw/Dropbox/CVUT/PROGTEST/du6/a.out)
==8885==    by 0x40177F: main (in /home/xerw/Dropbox/CVUT/PROGTEST/du6/a.out)
==8885==  Address 0x51f4f00 is not stack'd, malloc'd or (recently) free'd

valgrind: m_mallocfree.c:266 (mk_plain_bszB): Assertion 'bszB != 0' failed.
valgrind: This is probably caused by your program erroneously writing past the
end of a heap block and corrupting heap metadata.  If you fix any
invalid writes reported by Memcheck, this assertion failure will
probably go away.  Please try that before reporting this as a bug.

==8885==    at 0x3804C6CF: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==8885==    by 0x3804C812: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==8885==    by 0x38000883: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==8885==    by 0x380574EA: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==8885==    by 0x38057E03: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==8885==    by 0x380212DC: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==8885==    by 0x3802146A: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==8885==    by 0x3808F656: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==8885==    by 0x3809E68C: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)

sched status:
  running_tid=1

Thread 1: status = VgTs_Runnable
==8885==    at 0x4C2B3F8: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8885==    by 0x4008A5: read (in /home/xerw/Dropbox/CVUT/PROGTEST/du6/a.out)
==8885==    by 0x40177F: main (in /home/xerw/Dropbox/CVUT/PROGTEST/du6/a.out)

私は短い間ポインターを試してきたので、何が悪いのかわかりません。これを数時間解決しようとしましたが、何も思いつきませんでした。

私は何を間違っていますか?

4

1 に答える 1

1

問題は次の行にあるようです。

p = (char **) realloc(p, 2*i);

私はそれがすべきだと思います:

p = (char **) realloc(p, (2*i)*sizeof(char*));

つまり、要素を保持するために配列を増やしたいので、 のサイズの2*i倍数を割り当てる必要があります。2*ichar*

于 2012-11-24T20:58:19.163 に答える