![]() |
| | #1 |
| Registered User Join Date: Sep 2008
Posts: 33
| the input data is from a file named "bigint.txt" the first line tells how many lines follow. the first number tells add or subtract (1=add, 2=subtract) and the last 2 numbers on the line are the numbers to use. when subtracting it is suposed to always do the high - low regardless of order. the input data that i am using is as follows: Code: (not code just data) 10 1 123456789 987654321 2 9999999999 10000000000 2 10000000000 9999999999 1 3 5 2 7 7 2 0 5 1 19385838321938583832193858383219385838321938583832193858383219385838321938583832193858383219385838321938583832193858383200000000000000000000000000000000000000000000000000000000000000000000000000000000 95234567809123456780912345678091234567809123456780912345678091234567809123456780912345678091234567809123456780912345678091234567809123456780912345678091234567809123456780912345678091234567809123456780 2 19385838321938583832193858383219385838321938583832193858383219385838321938583832193858383219385838321938583832193858383200000000000000000000000000000000000000000000000000000000000000000000000000000000 95234567809123456780912345678091234567809123456780912345678091234567809123456780912345678091234567809123456780912345678091234567809123456780912345678091234567809123456780912345678091234567809123456780 2 23846098743650298740983098320576769760987394620943752836709832523980475208934750982365208743523 23846098743650298740983098320576769760987394620943752836709832523980475208934750982365208743523 1 935628126812131 148123782378218738287372 also if i just do one input the program also crashes though it dosent look like it. i marked both of the places that i have found that the program crashes. the first one is in the resize function and the second is in main. please help if you can, thank you! =) the code is a follows (sorry for the length but I'm not sure where the problem might be.): Code: //John Torres
//COP 3223-0002
//Assignment #3
//Febuary, 20, 2009
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct integer* read_integer(char* stringInt);
struct integer* read_integerRec(char* stringInt, int len);
void print(struct integer *p);
void printRec(struct integer *p, int list_len);
struct integer* add(struct integer *p, struct integer *q);
struct integer* addRec(struct integer *p, struct integer *q, int carry);
struct integer* subtract(struct integer *p, struct integer *q);
struct integer* subtractRec(struct integer *p, struct integer *q, int barrow);
int compare(struct integer *p, struct integer *q);
int compareRec(struct integer* p, struct integer* q, int len);
void FreeList(struct integer *p);
struct integer* ResizeList(struct integer *p);
struct integer* ResizeListRec(struct integer *p, int len);
int ListSize(struct integer *p);
struct integer{
int digit;
struct integer *next;
};
int main(void)
{
struct integer* head[3];
char number[201];
int file_len;
int test1;
int test2;
int i,j;
FILE *fin;
//open file and get number of file lines
fin = fopen("bigint.txt", "r");
fscanf(fin, "%d", &file_len);
//loop breaks after file is done
for(i = 0; i < file_len; i++)
{
//read operation type, 1=add, 2=sub
fscanf(fin,"%d", &test1);
//reads the 2 strings and converts them to numbers
for(j = 0; j < 2; j++)
{
fscanf(fin, "%s", number);
head[j] = read_integer(number);
}
//if add
if(test1 == 1)
{
//add function
head[2] = add(head[0], head[1]);
//resize
head[2] = ResizeList(head[2]);
//print operation
print(head[0]);
printf("\n+\n");
print(head[1]);
printf("\n=\n");
print(head[2]);
printf("\n\n");
system("pause");
}
//if subtract
else if(test1 == 2)
{
//subtract function
head[2] = subtract(head[0], head[1]);
//resize answer
head[2] = ResizeList(head[2]);
//check order
test2 = compare(head[0], head[1]);
//print operation
if(test2 == -1)
{//if second is larger
print(head[1]);
printf("\n-\n");
print(head[0]);
printf("\n=\n");
print(head[2]);
printf("\n");
system("pause");
}
else
{//if same or first is larger
print(head[0]);
printf("\n-\n");
print(head[1]);
printf("\n=\n");
print(head[2]);
printf("\n");
system("pause");
}
}
//if first number was not a 1 (add) or a 2 (sub)
else
{
printf("BAD DATA");
}
//free lists
FreeList(head[0]);
FreeList(head[1]);
///////////////////////////////////////////////second problem
///////////////////////////////////////////////dies here for just one line
FreeList(head[2]);
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
//Preconditions: the first parameter is string that stores
// only contains digits, doesn't start with
// 0, and is 50 or fewer characters long.
//
//Postconditions: The function will read the digits of the
// large integer character by character,
// convert them into integers and place them in
// nodes of a linked list. The pointer to the
// head of the list is returned.
//
//Discription:
////////////////////////////////////////////////////////////////////////////////
struct integer* read_integer(char* stringInt)
{
struct integer* temp;
int len;
//find number of digits
len = strlen(stringInt) - 1;
//build struct
return read_integerRec(stringInt, len);
}
struct integer* read_integerRec(char* stringInt, int len)
{
struct integer* temp;
//allocate memory
temp = (struct integer*) malloc(sizeof(struct integer));
//end case
if(len == 0)
{
temp->digit = (int) stringInt[0] - '0';
temp->next = NULL;
return temp;
}
//base case
else
{
temp->digit = (int) stringInt[len] - '0';
temp->next = read_integerRec(stringInt, len-1);
return temp;
}
}
////////////////////////////////////////////////////////////////////////////////
//Preconditions: p is a pointer to a big integer, stored in
// reverse order, least to most significant
// digit, with no leading zeros.
//
//Postconditions: The big integer pointed to by p is
// printed out.
//
//Discription:
////////////////////////////////////////////////////////////////////////////////
void print(struct integer *p)
{
int list_len;
//find list lenth
list_len = ListSize(p);
//print function
printRec(p, list_len);
}
void printRec(struct integer *p, int list_len)
{
struct integer* temp;
int i;
//end case
if(list_len == 0)
{
printf("%d", p->digit);
}
//base case
else
{
temp = p;
//move pointer to end of list
for(i = 0; i < list_len; i++)
{
temp = temp->next;
}
//print last number in list (first digit in number)
printf("%d", temp->digit);
//do it again
printRec(p, list_len-1);
}
}
////////////////////////////////////////////////////////////////////////////////
//Preconditions: p and q are pointers to big integers,
// stored in reverse order, least to most
// significant digit, with no leading zeros.
//
//Postconditions: A new big integer is created that stores
// the sum of the integers pointed to by p
// and q and a pointer to it is returned.
//
//Discription:
////////////////////////////////////////////////////////////////////////////////
struct integer* add(struct integer *p, struct integer *q)
{
return addRec(p, q, 0);
}
struct integer* addRec(struct integer *p, struct integer *q, int carry)
{
struct integer* big_number;
//allocate memory
big_number = (struct integer*) malloc(sizeof(struct integer));
//if nothing left to add
if(q->next == NULL && p->next == NULL)
{
big_number->digit = p->digit + q->digit + carry;
big_number->next = NULL;
return big_number;
}
//if q is has no more numbers
else if(q->next == NULL)
{
big_number->digit = q->digit+ p->digit + carry;
big_number->next = p->next;
return big_number;
}
//if p has no more numbers
else if(p->next == NULL)
{
big_number->digit = p->digit + q->digit + carry;
big_number->next = q->next;
return big_number;
}
//base case
else
{
//add
big_number->digit = p->digit + q->digit + carry;
//...carry the one...
if(big_number->digit > 9)
{
big_number->digit -= 10;
carry =1;
}
//reset carry
else
{
carry = 0;
}
//do it again
big_number->next = addRec(p->next, q->next, carry);
return big_number;
}
}
////////////////////////////////////////////////////////////////////////////////
//Preconditions: p and q are pointers to big integers,
// stored in reverse order, least to most
// significant digit, with no leading zeros.
//
//Postconditions: A new big integer is created that stores
// the absolute value of the difference
// between the two and a pointer to this is
// returned.
//
//Discription:
////////////////////////////////////////////////////////////////////////////////
struct integer* subtract(struct integer *p, struct integer *q)
{
struct integer* big_number;
int test;
//compare list to find grater number
test = compare(p, q);
//if first is grater
if(test == 1)
{
big_number = subtractRec(p, q, 0);
}
//if same or second is grater
else
{
big_number = subtractRec(q, p, 0);
}
return big_number;
}
struct integer* subtractRec(struct integer *p, struct integer *q, int barrow)
{
struct integer* big_number;
//allocate memory
big_number = (struct integer*) malloc(sizeof(struct integer));
//if q has no more numbers after this one
//and p is more then q + barrow
//end case
if(q->next == NULL && p->digit >= (q->digit + barrow))
{
big_number->digit = p->digit - q->digit - barrow;
big_number->next = p->next;
barrow = 0;
return big_number;
}
//if q and p have no more numbers after this one
//end case
else if(q->next == NULL && p->next == NULL)
{
big_number->digit = p->digit - q->digit - barrow;
big_number->next = NULL;
barrow = 0;
return big_number;
}
//if q has no more numbers after this one
//and q + barrow is more then p
//end case
else if(q->next == NULL)
{
big_number->digit = p->digit - q->digit - barrow + 10;
big_number->next->digit = p->next->digit - 1;
big_number->next->next = p->next->next;
barrow = 0;
return big_number;
}
//base case, p > q + barrow (dont need to barrow from next number
else if(p->digit >= (q->digit + barrow))
{
big_number->digit = p->digit - q->digit - barrow;
big_number->next = subtractRec(p->next, q->next, 0);
return big_number;
}
//base case, p < q + barrow (need to barrow from next number
else
{
big_number->digit = p->digit - q->digit - barrow + 10;
big_number->next = subtractRec(p->next, q->next, 1);
return big_number;
}
}
////////////////////////////////////////////////////////////////////////////////
//Preconditions: Both parameters of the function are
// pointers to struct integer.
//
//Postconditions: The function compares the digits of two
// numbers recursively and returns:
// -1 if the first number is smaller than the second,
// 0 if the first number is equal to the second number,
// 1 if the first number is greater than the second.
//
//Discription:
////////////////////////////////////////////////////////////////////////////////
int compare(struct integer *p, struct integer *q)
{
int p_len;
int q_len;
//finds number of digits in numbers
p_len = ListSize(p);
q_len = ListSize(q);
//compares lenths
if(p_len > q_len)
{//p is longer
return 1;
}
else if(p_len < q_len)
{//q is longer
return -1;
}
else
{//need more info
return compareRec(p, q, p_len);
}
}
int compareRec(struct integer* p, struct integer* q, int len)
{
struct integer* temp_p;
struct integer* temp_q;
int i;
//assing temp pointers
temp_p = p;
temp_q = q;
//end case
if(len == 1)
{
//if p<q
if(p->digit < q->digit)
{
return -1;
}
//if p>q
else if(p->digit > q->digit)
{
return 1;
}
//if p=q
else
{
return 0;
}
}
//base case
//move pointer to end of list (first number)
for(i = 1; i < len; i++)
{
temp_p = temp_p->next;
temp_q = temp_q->next;
}
//check
//if p>q
if(temp_p->digit > temp_q->digit)
{
return 1;
}
//if p<q
else if(temp_p->digit < temp_q->digit)
{
return -1;
}
//need more info, do it again
else
{
return compareRec(temp_p, temp_q, len-1);
}
}
////////////////////////////////////////////////////////////////////////////////
//Preconditions: A valid list header
//
//Postconditions: All nodes in list are freed
//
//Discription:
////////////////////////////////////////////////////////////////////////////////
void FreeList(struct integer *p)
{
struct integer* temp;
//base case
if(p != NULL)
{
//temp point to 2nd node
temp = p->next;
//do it again
FreeList(temp);
//free first node
free(p);
}
//end case (nothing...this is a void function)
}
////////////////////////////////////////////////////////////////////////////////
//Preconditions: Valid list of numbers
//
//Postconditions: returns a head pointer to a resied list. The new list has
// no ending zeros.
//
//Discription:
////////////////////////////////////////////////////////////////////////////////
struct integer* ResizeList(struct integer *p)
{
struct integer* temp;
int len;
//get list size (number of digits)
len = ListSize(p);
return ResizeListRec(p, len);
}
struct integer* ResizeListRec(struct integer *p, int len)
{
struct integer* temp;
int i;
//keeps the last number, no matter what (even 0)
//end case
if(len == 1)
{
temp = p->next;
p->next = NULL;
free(temp);
return p;
}
if(len == 0)
{
return p;
}
//assign temp
temp = p;
//put temp to last node (first digit)
for(i = 0; i < len - 1 ; i++)
{
temp = temp->next;
}
//check to see if digit is 0
if(temp->next->digit == 0)
{
//////////////////////////////////////first problem
//////////////////////////////////////Problem here after 5 calls on 3rd function
//////////////////////////////////////I think it is a memory issue
//free usless node
free(temp->next);
//changes pointer to null (end of list)
temp->next = NULL;
//do it again
return ResizeListRec(p, len - 1);
}
//if digit is not 0
//end case
else
{
return p;
}
}
////////////////////////////////////////////////////////////////////////////////
//Preconditions: Valid list of numbers
//
//Postconditions: Returns an int the size of the number of nodes in the list
//
//Discription:
////////////////////////////////////////////////////////////////////////////////
int ListSize(struct integer *p)
{
struct integer* temp;
int i;
//assign temp
temp = p;
//count number of digits in list
for(i = 0; temp->next != NULL; i++)
{
temp = temp->next;
}
return i;
}
|
| t014y is offline | |
| | #2 |
| subminimalist Join Date: Jul 2008 Location: NYC
Posts: 3,944
| This is a crazy idea. Are you supposed to use a linked list? Also, you might as well use a char as the data member of "integer", since the value will be 0-9, or -9 to 9. Do you get "double free" error messages on your system? I notice both your suspicious spots are amongst free() calls.
__________________ Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS |
| MK27 is offline | |
| | #3 |
| Registered User Join Date: Sep 2008
Posts: 33
| yes it is an assignment and i have to use linked list /sigh i don't get an error message at all (windos XP) but i think it is a memory problem. but i cant see how it is. |
| t014y is offline | |
| | #4 |
| subminimalist Join Date: Jul 2008 Location: NYC
Posts: 3,944
| try this: Code: #include <stdio.h>
#include <stdlib.h>
int main() {
void *ptr = malloc(666);
free(ptr);
puts("okay!");
free(ptr);
puts("okay!");
return 0;
}
__________________ Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS |
| MK27 is offline | |
| | #5 |
| Registered User Join Date: Sep 2008
Posts: 33
| when i ran that it worked... your program did not crash |
| t014y is offline | |
| | #6 |
| Complete Beginner Join Date: Feb 2009
Posts: 312
| Hi John, are you sure that you are supposed to store numbers in base 10? Your approach would make a lot more sense if you were to store numbers in a larger base, say 30000. This way, you have a lot more digits at hand, so the length of your lists would dramatically decrease and it would actually make sense. Maybe you can show us your assignment sheet. Greets, Philip
__________________ All things begin as source code. Source code begins with an empty file. -- Tao Te Chip |
| Snafuist is offline | |
| | #7 |
| Registered User Join Date: Sep 2008
Posts: 33
| there is no specifications about what base. i'll print the assignment here it made me print it like this...sorry Code: Computer Science I
Program 3: BigIntegers
Assigned: 2/9/09 (Monday)
Due: 2/20/09 (Friday 11:55pm over WebCT)
Note: For the Honors section, the program is due on 2/17/09.
The Problem
The unsigned int type in C requires 4 bytes of memory storage. With 4 bytes we can store integers as large as 232-1; but what if we need bigger integers, for example ones having hundreds of digits? If we want to do arithmetic with such very large numbers we cannot simply use the unsigned data type. One way of dealing with this is to use a different storage structure for integers, such as linked lists. If we represent an integer as a linked list, we can represent very large integers, where each digit is a node in the list. Since the integers are allowed to be as large as we like, linked lists will prevent the possibility of overflows in representation. However we need new functions to add, subtract, read and write these very large integers.
Write a program that will manipulate such arbitrarily large integers. Each integer should be represented as a linked list of digits. Your program will be required to read in big integers from a file, print big integers, and do addition or subtraction as required.
Your program should store each decimal digit (0-9) in a separate node of the linked list. In order to perform addition and subtraction more easily, it is better to store the digits in the list in the reverse order. For instance, the value 1234567890 might be stored as:
Your program should include the following functions:
a function that will read in an integer from the keyboard
a function that will print an integer that is stored as a linked list.
a function that will add two integers represented as linked lists and returns a pointer to the resulting list.
a function that compares two integers and returns -1 if the first is less than the second, 0 if they are equal, and 1 if the first is greater than the second.
a function that will subtract one integer from the other and return a pointer to the resulting list. Since youll be dealing with positive integers only, the result should be a positive number. To ensure that the result is integer you should subtract the smaller number from the larger one (or equal). For this purpose youre given a function that compares two large integers and returns 1, 0 or 1, depending on whether the first number is less than, equal to or greater than the second number.
Input/Output Specification
Your program should allow the user to do two things:
1) Add two big integers
2) Subtract to big integers
Instead of getting input from the user, you read in input from a file, "bigint.txt". (This will expedite the grading process.)
The input file format is as follows:
The first line will contain a single positive integer, n, representing the number of operations to carry out. The next n lines will contain one problem each. Each line will have three integers separated by white space. The first integer on each of these lines is guaranteed to either be 1 or 2, indicating addition and subtraction, respectively. The next two integers on the line will be the two operands for the problem. You may assume that these two integers are non-negative, are written with no leading zeros (unless the number itself is 0) and that the number of digits in either of the numbers will never exceed 200.
You should generate your output to the screen. In particular, you should generate one line of output per each input case. Your output should fit one of the two following formats:
X + Y = Z
X Y = Z
corresponding to which option was chosen. For the first option, always print the first operand first. For the second option, always print the larger of the two operands first. If the two operands are equal, the same number is printed both times.
Implementation Restrictions
You must use the following struct:
struct integer{
int digit;
struct integer *next;
}
Whenever you store or return a big integer, always make sure not to return it with any leading zeros. Namely, make sure that the last node in the linked list returned does NOT store 0, unless the number stored is 0, in that case a single node should have 0 in it.
The prototypes for the functions you will write are below. You may include other functions, but it is required for these functions to be included.
//Preconditions: the first parameter is string that stores
// only contains digits, doesn't start with
// 0, and is 50 or fewer characters long.
//Postconditions: The function will read the digits of the
// large integer character by character,
// convert them into integers and place them in
// nodes of a linked list. The pointer to the // head of the list is returned.
struct integer* read_integer(char* stringInt);
//Preconditions: p is a pointer to a big integer, stored in
// reverse order, least to most significant
// digit, with no leading zeros.
//Postconditions: The big integer pointed to by p is
// printed out.
void print(struct integer *p);
//Preconditions: p and q are pointers to big integers,
// stored in reverse order, least to most
// significant digit, with no leading zeros.
//Postconditions: A new big integer is created that stores
// the sum of the integers pointed to by p
// and q and a pointer to it is returned.
struct integer* add(struct integer *p, struct integer *q);
//Preconditions: p and q are pointers to big integers,
// stored in reverse order, least to most
// significant digit, with no leading zeros.
//Postconditions: A new big integer is created that stores
// the absolute value of the difference
// between the two and a pointer to this is
// returned.
struct integer* subtract(struct integer *p, struct integer *q);
//Preconditions: Both parameters of the function are
// pointers to struct integer.
//Postconditions: The function compares the digits of two
// numbers recursively and returns:
// -1 if the first number is smaller than the second,
// 0 if the first number is equal to the second number,
// 1 if the first number is greater than the second.
int compare(struct integer *p, struct integer *q);
Sample Input File
3
1 8888888888 2222222222
2 9999999999 10000000000
2 10000000000 9999999999
Corresponding Output
8888888888 + 2222222222 = 11111111110
10000000000 9999999999 = 1
10000000000 9999999999 = 1
Deliverables
Turn in a single file, bigintll.c, over WebCT that solves the specified problem. If you decide to make any enhancements to this program, clearly specify them in your header comment so the grader can test your program accordingly.
Last edited by t014y; 02-20-2009 at 03:15 PM. |
| t014y is offline | |
| | #8 |
| subminimalist Join Date: Jul 2008 Location: NYC
Posts: 3,944
| You mean it printed "okay!" TWICE? I think you're wrong! Which means that you aren't getting a double-free warning. Try commenting out all the free() calls temporarily and see if that changes anything. ps. go back and change the [tags] around the assignment to "quote" instead of "code" so there will be line breaks...
__________________ Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS Last edited by MK27; 02-20-2009 at 03:24 PM. |
| MK27 is offline | |
| | #9 |
| Registered User Join Date: Sep 2008
Posts: 33
| yes it printed "okay" twice before the program ended |
| t014y is offline | |
| | #10 | |
| Complete Beginner Join Date: Feb 2009
Posts: 312
| There is: Quote:
I don't have the patience to go though your code, but when you encounter strange problems with free(), it's generally a good idea to check for off-by-one errors and the like. If the heap is corrupted, sometimes you'll detect that only after calling free(). I once knew why this is the case, but I try hard to forget it again. Greets, Philip
__________________ All things begin as source code. Source code begins with an empty file. -- Tao Te Chip | |
| Snafuist is offline | |
| | #11 |
| Registered User Join Date: Sep 2008
Posts: 33
| oh i guess it does... we did this same program with dynamically allocated arrays. and i didn't have this problem but that was an array not a linked list... |
| t014y is offline | |
| | #12 |
| subminimalist Join Date: Jul 2008 Location: NYC
Posts: 3,944
| Hmmm -- I have to ask my own question about this!
__________________ Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS |
| MK27 is offline | |
| | #13 |
| Registered User Join Date: Sep 2008
Posts: 33
| I'm getting off line now. any input will be helpful. thank you |
| t014y is offline | |
| | #14 |
| Registered User Join Date: Sep 2008
Posts: 33
| I'm getting off line now. any input will be helpful. thank you |
| t014y is offline | |
| | #15 |
| subminimalist Join Date: Jul 2008 Location: NYC
Posts: 3,944
| Are you trying to be passive aggressive? You might want to read this and investigate the issue further. A double free will screw with you, and you need to rule that out.
__________________ Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS |
| MK27 is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Unknown memory leak with linked lists... | RaDeuX | C Programming | 6 | 12-07-2008 04:09 AM |
| Link List Insert prob | Bebs | C Programming | 8 | 12-03-2008 10:28 PM |
| reading data from a file - link list | peter_hii | C++ Programming | 7 | 10-25-2006 09:11 AM |
| compiler build error | KristTlove | C++ Programming | 2 | 11-30-2003 10:16 AM |
| singly linked list | clarinetster | C Programming | 2 | 08-26-2001 10:21 PM |