2

サイズが不明な配列を作りたいのですが、このようにしていいのでしょうか?:

int *array,var,i=0;
FILE *fp;
fopen=("/home/inputFile.txt","r");
fscanf(fp,"%d",&var);
while(fp!=NULL)
{
    if(var>0)
   {
        array=malloc(sizeof(int));
        array[i++]=var
   }
   fscanf(fp,"%d",&var);
}
4

3 に答える 3

1

基本的なことは、ARRAY は DYNAMIC ではなく STATIC です。

于 2013-09-13T10:07:49.497 に答える
1

これはばかげた誤りであり、メモリ リークと未定義の動作でいっぱいです。

ただし、正しい方法の 1 つであるリンクされたリストの方法からそれほど離れているわけではありません。

struct linked_int
{
    int value;
    struct linked_int* pNext;
};

struct linked_int *pHead=NULL;
struct linked_int **ppTail = &pHead;
int* array = NULL;
int cpt=0;
/*Read file, building linked list*/
FILE *fp = fopen("/home/inputFile.txt","r");
if(fp != NULL)
{
    int var;
    while(fscanf(fp,"%d",&var)==1)
    {
        if(var>0)
        {
            struct linked_int *pNew = malloc(sizeof(struct linked_int));
            pNew->value = var;
            pNew->pNext = NULL;
            /*Append at the tail of the list*/
            *ppTail = pNew;
            ppTail = &(pNew->pNext);

            cpt++;
        }
    }
    fclose(fp);
}

/*Copy from the linked list to an array*/
array = malloc(sizeof(int) * cpt);
if(array != NULL)
{
    int i;
    struct linked_int const *pCur = pHead;
    for(i=0 ; i<cpt ; i++)
    {
        arr[i] = pCur->value;
        pCur = pCur->pNext;
    }
}

/*Free the linked list*/
while(pHead != NULL)
{
    struct linked_int *pDelete = pHead;
    pHead = pHead->pNext;
    free(pDelete);
}
ppTail = &pHead;

他の方法:

もう 1 つの正しい方法は、reallocサイズが拡大し続ける配列を再割り当てする方法です (通常、幾何学的な増加を伴います。つまり、配列のサイズに毎回 1.5 などの数値を掛けます)。これを行う間違った方法は、毎回配列サイズに 1 を追加することです。

次のようになります。

int arrayCapacity=0, numberOfItems=0;
int* array = NULL;
int var;
while(fscanf(fp, "%d", &var)==1)
{
    if(numberOfItems >= arrayCapacity)
    {
        /*Need to resize array before inserting*/
        const int MIN_CAPACITY = 4;
        const double GROWTH_RATE = 1.5;
        int newCapacity = arrayCapacity<MIN_CAPACITY ? MIN_CAPACITY : (int)(arrayCapacity*GROWTH_RATE);
        int* tmp = realloc(array, newCapacity*sizeof(int));
        if(tmp==NULL)
        {
            /*FAIL: can't make the array bigger!*/
        }
        else
        {
            /*Successfully resized the array.*/
            array = tmp;
            arrayCapacity = newCapacity;
        }
    }

    if(numberOfItems >= arrayCapacity)
    {
        puts("Cannot add, array is full and can't be enlarged.");
        break;
    }
    else
    {
        array[numberOfItems] = var;
        numberOfItems++;
    }
}
/*Now we have our array with all integers in it*/

明らかな結果として、このコードでは、配列内に未使用のスペースが存在する可能性があります。これは問題ではありません。

于 2013-09-13T10:08:49.937 に答える
1

sizeof(int) は 4 を返します (そして、応答で 2 または 8 と言うコンパイラ/設定はほとんどないことに注意してください)。したがって、コードは 4 バイト長の配列を割り当てることと同じです。

サイズが不明な配列が必要な場合は、std::vector などの STL コンテナーを利用する価値があります (バックグラウンドで割り当てとサイズ変更を管理するため)。「プレーン C」スコープに固執する場合は、TSTL2CL ライブラリに興味があるかもしれません: http://sourceforge.net/projects/tstl2cl

于 2013-09-13T10:06:52.100 に答える