これはばかげた誤りであり、メモリ リークと未定義の動作でいっぱいです。
ただし、正しい方法の 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*/
明らかな結果として、このコードでは、配列内に未使用のスペースが存在する可能性があります。これは問題ではありません。