免責聲明,這是一個學校作業的幫助。這就是說,我的問題只發生在大約50%的時間。這意味着如果我編譯並運行我的代碼而不進行編輯,有時它會將其貫穿到最後,而其他時間則不會。通過使用多個打印語句,我確切地知道問題發生的位置。這個問題發生在我第二次打電話給hugeDestroyer(正好在打印354913546879519843519843548943513179部分之後),更確切地說是在免費(p->數字)部分。Calloc/Malloc並釋放空間太大或太大?
我試過了這裏找到的建議(free a pointer to dynamic array in c),並將指針設置爲NULL後釋放它們沒有運氣。
通過一些挖掘和靈魂搜索,我已經瞭解了一些關於(How do malloc() and free() work?)的免費作品,我想知道我的問題是來自用戶Juergen在他的回答中提到的,並且我正在「覆蓋」管理數據免費清單。
要清楚,我的問題是雙重的。
是免費的(p->數字)在語法上是正確的,如果是這樣的話,爲什麼我在運行代碼時會遇到一半的麻煩?其次,我如何防範這種行爲在我的職能?
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
typedef struct HugeInteger
{
// a dynamically allocated array to hold the digits of a huge integer
int *digits;
// the number of digits in the huge integer (approx. equal to array length)
int length;
} HugeInteger;
// Functional Prototypes
int str2int(char str) //converts single digit numbers contained in strings to their int value
{
return str - 48;
}
HugeInteger *parseInt(unsigned int n)
{
int i = 0, j = 0;
int *a = (int *)calloc(10, sizeof(int));
HugeInteger *p = (HugeInteger *)calloc(1, sizeof(HugeInteger));
if(n == 0)
{
p->digits = (int *)calloc(1, sizeof(int));
p->length = 1;
return p;
}
while(n != 0)
{
a[i] = n % 10;
n = n/10;
i++;
}
p->length = i;
p->digits = (int *)calloc(p->length, sizeof(int));
for(i = 0; i <= p->length; i++, j++)
p->digits[j] = a[i];
return p;
}
HugeInteger *parseString(char *str) //notice datatype is char (as in char array), so a simple for loop should convert to huge int array
{
int i = 0, j = 0;
HugeInteger *p = (HugeInteger *)calloc(1, sizeof(HugeInteger));
if(str == NULL)
{
free(p);
p = NULL;
return p;
}
else
{
for(i=0; str[i] != '\0'; i++)
;
p->length = i;
p->digits = (int *)calloc(p->length, sizeof(int));
for(; i >= 0; i--)
p->digits[j++] = str2int(str[i - 1]);
}
return p;
} //end of HugeInteger *parseString(char *str)
HugeInteger *hugeDestroyer(HugeInteger *p)
{
//printf("No problem as we enter the function\n");
if(p == NULL)
return p;
//printf("No problem after checking for p = NULL\n");
if(p->digits == NULL)
{
free(p);
p = NULL;
return p;
}
//printf("No Problem after checking if p->digits = NULL\n");
//else
//{
free(p->digits);
printf("We made it through free(p->digits)\n");
p->digits = NULL;
printf("We made it through p->digits = NULL\n");
free(p);
printf("We made it through free(p)\n");
p = NULL;
printf("We made it through p = NULL\n");
return p;
//}
//return NULL;
}//end of HugeInteger *hugeDestroyer(HugeInteger *p)
// print a HugeInteger (followed by a newline character)
void hugePrint(HugeInteger *p)
{
int i;
if (p == NULL || p->digits == NULL)
{
printf("(null pointer)\n");
return;
}
for (i = p->length - 1; i >= 0; i--)
printf("%d", p->digits[i]);
printf("\n");
}
int main(void)
{
HugeInteger *p;
hugePrint(p = parseString("12345"));
hugeDestroyer(p);
hugePrint(p = parseString("354913546879519843519843548943513179"));
hugeDestroyer(p);
hugePrint(p = parseString(NULL));
hugeDestroyer(p);
hugePrint(p = parseInt(246810));
hugeDestroyer(p);
hugePrint(p = parseInt(0));
hugeDestroyer(p);
hugePrint(p = parseInt(INT_MAX));
hugeDestroyer(p);
//hugePrint(p = parseInt(UINT_MAX));
//hugeDestroyer(p);
return 0;
}
您是否嘗試過使用調試器? –
'for(; i> = 0; i - )'循環比你分配的空間多寫入一個數字(例如,如果'p-> digits == 1'那麼你爲1個int分配空間,但是這個循環運行兩次,'i == 1',然後'i == 0',第二次迭代寫入'p-> digits [1]',這是超出範圍的) –
我已經使用了帶有某些效果的codeBlocks的調試器,是什麼讓我到免費(p->數字)部分,但它只是有一個內存地址作爲註釋指向該行,並沒有真正有用的除了顯示我。 我確實改變了你指出的片段(; i - 1> = 0; i--),現在我可以在segfaulting之前將它放到INT_MAX部分,所以這絕對是進步。似乎我的問題可能不是免費的,但超越了界限。 –