所以我运行程序来克服整数溢出,而我正在调试它运行第一个命令hugePrint(p = parseString(" 12345"));没有问题。它运行代码之后,hugeDestroyer(p);并释放内存没有问题。一旦我在Ubuntu中运行下一行代码,我就会遇到一个段错误,它甚至不会打印数字,但是在Windows上它会打印出#34; 354913546879519843519843548943513179"然后在运行hugeDestroyer(p)之后给我一个seg错误;再次。还有问题通过我的parseString()函数运行NULL值。非常感谢任何帮助,以揭示seg故障。
// main
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "Fibonacci.h"
// 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;
}
//fibonacci.c
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "Fibonacci.h"
// Functional Prototypes
/*
HugeInteger *hugeAdd(HugeInteger *p, HugeInteger *q)
{
}
*/
HugeInteger *hugeDestroyer(HugeInteger *p)
{
int i;
if ( p == NULL )
return NULL;
if( p->length != NULL)
free(p->length);
if ( p->digits != NULL )
{
for ( i = 0; i < p->length; i++)
free( p->digits[i] );
free( p->digits );
}
free( p );
return NULL;
}
HugeInteger *parseString(char *str)
{
int counter, reverseCount = 0;
HugeInteger *numArray = malloc(sizeof(HugeInteger));
if ( str == NULL)
{
return NULL;
}
//checks for NULL pointer
if ( numArray == NULL)
{
return NULL;
}
// Dynamically allocate memory for array of numbers
numArray->length = strlen(str);
numArray->digits = malloc( sizeof(int) * numArray->length+1);
if ( numArray->digits == NULL)
return NULL;
for( counter = numArray->length - 1 ; counter >= 0 ; counter--)
{
numArray->digits[reverseCount] = str[counter];
// Handles conversion from ASCII to integer format
switch(numArray->digits[reverseCount])
{
case 48:
numArray->digits[reverseCount] = 0;
break;
case 49:
numArray->digits[reverseCount] = 1;
break;
case 50:
numArray->digits[reverseCount] = 2;
break;
case 51:
numArray->digits[reverseCount] = 3;
break;
case 52:
numArray->digits[reverseCount] = 4;
break;
case 53:
numArray->digits[reverseCount] = 5;
break;
case 54:
numArray->digits[reverseCount] = 6;
break;
case 55:
numArray->digits[reverseCount] = 7;
break;
case 56:
numArray->digits[reverseCount] = 8;
break;
case 57:
numArray->digits[reverseCount] = 9;
break;
default:
numArray->digits[reverseCount] = 0;
break;
}
reverseCount++;
}
return numArray;
}
HugeInteger *parseInt(unsigned int n)
{
HugeInteger *number = malloc(sizeof(HugeInteger));
if( number == NULL )
return NULL;
if(n > UINT_MAX )
return NULL;
number = n;
return number;
}
unsigned int *toUnsignedInt(HugeInteger *p)
{
unsigned int *newInteger = malloc(sizeof(unsigned int));
if( newInteger == NULL)
{
return NULL;
}
if (p == NULL || p > UINT_MAX )
{
return NULL;
}
newInteger = p;
return newInteger;
}
/*
HugeInteger *fib(int n)
{
// base cases: F(0) = 0, F(1) = 1
if (n < 2)
return n;
// definition of Fibonacci: F(n) = F(n – 1) + F(n - 2)
return fib(n – 1) + fib(n – 2);
}
*/
//fibonacci.h
#ifndef __FIBONACCI_H
#define __FIBONACCI_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
HugeInteger *hugeAdd(HugeInteger *p, HugeInteger *q);
HugeInteger *hugeDestroyer(HugeInteger *p);
HugeInteger *parseString(char *str);
HugeInteger *parseInt(unsigned int n);
unsigned int *toUnsignedInt(HugeInteger *p);
HugeInteger *fib(int n);
#endif
答案 0 :(得分:1)
您的代码中存在多个问题。
当你malloc
得到一个HugeInteger时,你没有初始化返回0的内存。由于你在str == NULL
时方法中有早期返回,所以结构的成员没有被初始化,所以当你在上面调用hugeDestroyer时,你会得到未定义的行为,因为你不知道你的struct中的内存是什么样的。很可能p-&gt;数字不为空,它会尝试从中释放内存。
在hugeDestroyer中你有这个代码
if( p->length != NULL)
free(p->length);
length是一个int,并且没有使用malloc动态分配,因此在此调用free会将int解释为地址。再次出现未定义的行为。
同样在hugeDestroyer中,您有此代码
for ( i = 0; i < p->length; i++)
free( p->digits[i] );
free( p->digits );
这也是错误的,p->digits
以正确的大小分配一次。您只需要调用free(p->digits)
,因为c运行时会记住分配的大小。您的seg故障再次由数字数组中的自由解释值作为要释放的内存地址引起。
答案 1 :(得分:1)
假设您的巨大整数表示将使用十进制数字,ParseInt
将需要将参数分解为单个十进制数字。试一试:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "Fibonacci.h"
void hugeDestroyer(HugeInteger *p)
{
if ( p != NULL ) {
free( p->digits );
free( p );
}
}
HugeInteger *parseString(char *str)
{
HugeInteger *huge;
int i;
if (str == NULL)
goto error1;
if ((huge = malloc(sizeof *huge)) == NULL)
goto error1;
huge->length = strlen(str);
if ((huge->digits = malloc(huge->length * sizeof *huge->digits)) == NULL)
goto error2;
for (i = 0; i < huge->length; i++) {
huge->digits[huge->length-i-1] =
(str[i] >= '0' && str[i] <= '9') ? str[i] - '0' : 0;
}
return huge;
//error3:
// free(huge->digits);
error2:
free(huge);
error1:
return NULL;
}
HugeInteger *parseInt(unsigned int n)
{
HugeInteger *huge;
int digits[10]; // largest 32-bit unsigned integer has 10 digits in base 10
int length;
if ((huge = malloc(sizeof *huge)) == NULL)
goto error1;
length = 0;
do {
digits[length++] = n % 10;
n /= 10;
}
while (n);
huge->length = length;
if ((huge->digits = malloc(huge->length * sizeof *huge->digits)) == NULL)
goto error2;
memcpy(huge->digits, digits, huge->length * sizeof *huge->digits);
return huge;
//error3:
// free(huge->digits);
error2:
free(huge);
error1:
return NULL;
}
答案 2 :(得分:0)
我只看了你的HugeInteger
结构,注意length
不是指针。不要释放它!
正如@EricFortin所提到的,在调用malloc()
后你没有初始化你的结构:
HugeInteger *numArray = malloc(sizeof(HugeInteger));
numArray->length = 0 ; // add me
numArray->digits = NULL ; // add me
同样的事情:
HugeInteger *number = malloc(sizeof(HugeInteger));
numArray->length = 0 ; // add me
numArray->digits = NULL ; // add me
每次从任何ParseInt()
或ParseString()
函数提前返回时,都会因为没有释放HugeInteger
指针而导致内存泄漏。
这样做(第一次我错了,另外感谢@EricFortin):
for ( i = 0; i < p->length; i++) // remove me
free( p->digits[i] ); // remove me
free( p->digits ); // keep me