1

stdinから読み込もうとしています(ファイルから値を渡します)。文字列から各文字を読み取り、動的に割り当てられた文字列ポインタに格納しています。必要に応じて、メモリを再割り当てします。できるだけ多くのキャラクターを獲得しようとしています。私はそれを100,000文字に制限することができますが。しかし、reallocはいくつかの反復後に失敗します。しかし、mallocでの最初の初期化中にチャンクサイズを大きく(たとえば1048567)指定すると、文字列を完全に読み取ることができます。どうしてこれなの?

以下は私のプログラムです:

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

int display_mem_alloc_error();

enum {
    CHUNK_SIZE = 31    //31 fails. But 1048567 passes.
};

int display_mem_alloc_error() {
    fprintf(stderr, "\nError allocating memory");
    exit(1);
}

int main(int argc, char **argv) {
    int numStr;                  //number of input strings
    int curSize = CHUNK_SIZE;    //currently allocated chunk size
    int i = 0;                   //counter
    int len = 0;                 //length of the current string
    int c;                       //will contain a character
    char *str = NULL;            //will contain the input string
    char *str_cp = NULL;         //will point to str
    char *str_tmp = NULL;        //used for realloc

    str = malloc(sizeof(*str) * CHUNK_SIZE);
    if (str == NULL) {
        display_mem_alloc_error();
    }    
    str_cp = str;   //store the reference to the allocated memory

    scanf("%d\n", &numStr);   //get the number of input strings
    while (i != numStr) {
        if (i >= 1) {   //reset
            str = str_cp;
            len = 0;
            curSize = CHUNK_SIZE;
        }
        c = getchar();
        while (c != '\n' && c != '\r') {
            *str = (char *) c;
            //printf("\nlen: %d -> *str: %c", len, *str);
            str = str + 1;
            len = len + 1;
            *str = '\0';
            c = getchar();
            if (curSize / len == 1) {
                curSize = curSize + CHUNK_SIZE;
                //printf("\nlen: %d", len);
                printf("\n%d \n", curSize);    //NB: If I comment this then the program simply exits. No message is displayed.
                str_tmp = realloc(str_cp, sizeof(*str_cp) * curSize);
                if (str_tmp == NULL) {
                    display_mem_alloc_error();
                }
                //printf("\nstr_tmp: %d", str_tmp);
                //printf("\nstr: %d", str);
                //printf("\nstr_cp: %d\n", str_cp);
                str_cp = str_tmp;
                str_tmp = NULL;
            }
        }
        i = i + 1;
        printf("\nlen: %d", len);
        //printf("\nEntered string: %s\n", str_cp);
    }
    str = str_cp;
    free(str_cp);
    free(str);
    str_cp = NULL;
    str = NULL;
    return 0;
}

ありがとう。

4

2 に答える 2

6

あなたがrealloc

str_tmp = realloc(str_cp, sizeof(*str_cp) * curSize);
if (str_tmp == NULL) {
    display_mem_alloc_error();
}
//printf("\nstr_tmp: %d", str_tmp);
//printf("\nstr: %d", str);
//printf("\nstr_cp: %d\n", str_cp);
str_cp = str_tmp;
str_tmp = NULL;

str_cp新しいメモリブロックをポイントしますが、それでもstr古い、現在はfreedブロックをポイントします。したがって、次の反復でポイントにアクセスするstrと、未定義の動作が呼び出されます。

strに関してのオフセットを保存する必要がありますstr_cp。再割り当て後、str古いオフセットで新しいブロックをポイントします。

そして*str = (char *) c;間違っていますが、機能的に正しいと同等である可能性はゼロではありません*str = c;

于 2012-10-26T12:08:45.480 に答える
2
     *str = (char *) c;

この行は間違っています。

strはへのポインタでcharあり、*strはですが、へcharのポインタを割り当てています。これはCでは実行できません。charchar

さらに:

scanf("%d\n", &numStr);

\nインコールはscanfおそらくあなたが期待するものではありません:

http://c-faq.com/stdio/scanfhang.html

そしてまた:

str = str_cp;
free(str_cp);
free(str);

ここにダブルフリーがあります。割り当て後、同じ値になりますstrstr_cp

free(str_cp);
free(str);

あなたがするかのようです:

free(str);
free(str);

これは未定義の動作です(2回解放することはできません)。

于 2012-10-26T12:06:40.693 に答える