我試圖寫一個程序,其第一動態初始化爲100個INT元件隊列陣列收縮陣列。每當隊列已滿並且另一個元素應該排隊時,原始數組應該是其大小的兩倍,以便可以插入新元素。在元素出隊的情況下,隊列所包含的元素數量低於其實際大小的一半時,隊列大小應該減半。然而,它的規模應該不會低於10擴展和使用的realloc
我試圖擴大和縮小與realloc的數組,但我在理解其機制的一些問題,返回新的指針時尤其如此。下面是我的程序(有一些冗餘printf
爲debugging
原因):
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <iso646.h>
void enqueue(int arr[], int* lastElementIdx, int *length, int element);
int dequeue (int arr[], int* lastElementIdx, int *length);
void printQueue(const int arr[], int lastElementIdx);
int expandArray(int *arr, int length);
int shrinkArray(int *arr, int length, bool min);
void test1(int *arr, int* lastElementIdx, int *length)
{
int* temp = arr;
printf("\nprintQueue #1:\n"); //print queue, should be empty
printQueue(temp, *lastElementIdx);
for(int i = 1; i <= 100; i++) //insert elemnts to queue
enqueue(temp, lastElementIdx, length, i);
printf("\nprintQueue #2:\n"); //print queue
printQueue(temp,*lastElementIdx);
printf("\nAusgabe von dequeue:\n"); // dequeue array
while(*lastElementIdx > *length/4)
printf("\naddress: %p\tElement: %d\n", temp, dequeue(temp, lastElementIdx, length));
free(temp);
}
void test2(int *arr, int* lastElementIdx, int *length)
{
int *temp = arr;
printf("\n************\nEnqueue beyond queue[N-1]:\n");
puts("Queue aufbauen...");
for(int i = 1; i <= 150; i++)
enqueue(temp, lastElementIdx, length, i);
printf("\nprintQueue:\n");
printQueue(temp,*lastElementIdx);
printf("\nDequeue:\n");
while(*lastElementIdx > *length/4)
printf("\naddress: %p\tElement: %d\n", temp, dequeue(temp, lastElementIdx, length));
free(temp);
}
int main(int argc, char const *argv[])
{
int startingPoint = -1, *lastElementIdx = &startingPoint, N = 100, *length = &N;
int *queue = (int*) calloc(*length, sizeof(*queue));
test2(queue, lastElementIdx, length);
queue = (int*) calloc(*length, sizeof(*queue));
test1(queue, lastElementIdx, length);
return 0;
}
int expandArray(int *arr, int length)
{
/*function to double the array size*/
length *= 2;
int *temp;
temp = (int*) realloc(arr, sizeof(*arr)*length);
if (!temp) {
free(temp);
}
else{
if (arr != temp) {
free(arr);
arr = temp;
}
else{
arr = temp;
}
}
printf("EXPAND ARRAY: %p\n", arr);
return length;
}
int shrinkArray(int *arr, int length, bool min)
{
/*function that cuts array in half*/
int *temp;
if (min){
length = 10;
}
else{
length /= 2;
}
temp = (int*) realloc(arr,sizeof(*arr)*length);
if (!temp) {
free(temp);
}
else{
arr = temp;
}
printf("SHRINK ARRAY: %p\n",arr);
return length;
}
void enqueue(int arr[], int* lastElementIdx, int *length, int element)
{
if (*lastElementIdx < *length - 1){ //checks if there's space for another element
arr[*lastElementIdx + 1] = element; //if yes, insert element after lastElementIdx
(*lastElementIdx)++; //increment lastElementIdx
}
else{
*length = expandArray(arr, *length); //if not, expand array
}
}
int dequeue (int arr[], int* lastElementIdx, int *length)
{
printf("address before:\t%p\tLast Element: %d\tLength: %d\n", arr,*lastElementIdx, *length);
int *p = arr;
if(*lastElementIdx > -1){ //Checks if there is an element in the queue
if (*lastElementIdx + 2 < *length/2 and *lastElementIdx + 2 > 10) {
bool min = false;
*length = shrinkArray(arr, *length, min);
}
else if (*lastElementIdx + 2 < 10){
bool min = true;
*length = shrinkArray(arr, *length, min);
}
(*lastElementIdx)--; //shift position of last element
printf("address afterw:\t%p\tLast Element: %d\tLength: %d\n", arr, *lastElementIdx,*length);
return *(p + *lastElementIdx + 1);
}
return 0;
}
void printQueue(const int arr[], int lastElementIdx)
{
while(lastElementIdx > -1){
printf("%d\t", *(arr + lastElementIdx));
lastElementIdx--;
}
}
不過,我不斷收到2個錯誤。第一個是這裏:
if (arr != temp) {
free(arr);
arr = temp;
}
說error for object 0x1001013b0: pointer being freed was not allocated
。 我實現了擺在首位這一行,因爲過了一段時間我有時想通了的重新分配內存的變化指針的地址。在這兩種情況下,有時執行程序malloc: *** error for object 0x100500000: pointer being realloc'd was not allocated
我也應該補充,如果我刪除if statement
我仍然不斷收到錯誤,這一次在這條線是:
temp = (int*) realloc(arr, sizeof(*arr)*length);
消息之中沒有任何問題。在後一種情況下,錯誤在expandArray
中的重新分配行與shrinkArray
中的重新分配行之間交替。 我真的不明白爲什麼會這樣,以及如何處理這種情況時realloc
返回新的指針地址。受類似帖子的啓發,我嘗試了不同的方法,例如將int **arr
而不是int *arr
傳遞給expandArray
和shrinkArray
。我也嘗試了不同的方法來釋放後的realloc原始數組一樣
temp = (int*) realloc(arr,sizeof(*arr)*length);
if (!temp) {
free(temp);
}
else{
free(arr);
arr = temp;
}
具有相同的錯誤消息
始終。我希望在每個測試函數之後釋放內存,並在調用第二個測試函數之前在隊列數組中分配新內存以解決問題,但事實上並不如此。
我真的很感激任何形式的這一幫助。
評論:使用''標題是很不尋常的。目光觀察代碼,我發現'&和'代替'&&'的一個實例。我想知道這是否是一個優勢。這在技術上不是錯誤的;不過,這很不尋常。 –
好的謝謝。其實我更喜歡玩它,因爲幾天前我讀到了它。這也是我第一次也是唯一一次使用它。 –
注意:1)'realloc()'可能在內存不足的情況下返回'NULL',如'realloc(arr,sizeof(* arr)* length);',如果長度爲0。所以不是'if(!temp){free(temp);'use'if(!temp && length!= 0){free(temp);'更好的是,事先檢測if(length <= 0)只需調用'free(arr)'。 2)最好使用'size_t長度'。 – chux