【发布时间】:2010-09-11 16:42:03
【问题描述】:
当编译一个包含这个特定函数的程序时,
/*
* Function read_integer
*
* @Parameter CHAR* stringInt
*
* Parameter contains a string representing a struct integer.
* Tokenizes the string by each character, converts each char
* into an integer, and constructs a backwards linked list out
* of the digits.
*
* @Return STRUCT* Integer
*/
struct integer* read_integer( char* stringInt )
{
int i, n;
struct integer *curr, *head;
int numDigits = strlen( stringInt ); // Find the length of the struct integer
char *tok;
head = NULL;
for( i = 0; i < numDigits; i++ )
{
tok = strtok( stringInt, NULL ); // Tokenize the string by each char
n = atoi( tok[i] ); // Convert char to an integer
curr = (struct integer *) malloc (sizeof( struct integer )); // Allocate memory for node
curr->digit = n; // Digit of current node is assigned to n
curr->next = head; // Move to the next node in the list.
head = curr; // Move head up to the front of the list.
}
return head; // Return a pointer to the first node in the list.
}
我收到警告:
bigintII.c: In function ‘read_integer’:
bigintII.c:167: warning: passing argument 1 of ‘atoi’ makes pointer from integer without a cast
//usr/include/stdlib.h:148: note: expected ‘const char *’ but argument is of type ‘char’
我尝试了几种不同的方法(主要是在黑暗中拍摄)来消除警告,但无济于事。谁能指出我正确的方向?
---///---
下面是原始的愚蠢问题,因为我不想成为那个人而离开。---
我正在尝试调试我的 CS1 作业,以便我可以完成它并继续做一些有趣的事情(比如从事我的 CLisp 研究),但我遇到了一个我无法克服的错误。现在,我知道任务还没有完成(即,即使我让它运行,它也不会按照我的意愿去做)但我不需要帮助(此外,那会有什么乐趣是?)。如果有人能帮我弄清楚为什么以下代码在编译和执行时会产生无用的(对我而言)Segmentation fault (core dumped),那太好了。
/*
* File: struct integer.c
* Description: Assignment in using Linked Lists
* in order to perform struct integer addition and subtraction.
*
* Created on September 1, 2010, 11:38 AM
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Constant Definitions
#define ADD 1
#define SUB 2
// Output file
char *fName = "out.txt";
FILE *outFile;
/*
* Create a prototype of a single
* node in the Linked List.
* Each node will represent a single
* integer comprising one part of a struct integer.
*/
struct integer
{
int digit;
struct integer *next;
};
// Function Prototypes
struct integer* read_integer( char *stringInt );
struct integer* add( struct integer *p, struct integer *q );
struct integer* subtract( struct integer *p, struct integer *q);
int compare( struct integer *p, struct integer *q );
void print( struct integer *p );
// Main function
int main( )
{
//Variable initialization
/*
* Initialize pointers to the linked lists.
* One, *head, will always point to the
* first element, the head, of the list.
* The other element, *curr, will point to the
* node currently being accessed, and will be
* used to traverse the list.
*/
struct integer* pHead;
struct integer* qHead;
struct integer* tHead; // Used to contain the total
int numOps, oper, i;
const char *fileName = "struct integer.txt";
char bigintstr[200];
FILE *inputFile;
// Open output file
outFile = fopen(fName, "a+");
// Open up the input file for reading
inputFile = fopen(fileName, "r");
// Read in the number of operations to be performed
fscanf(inputFile, "%d", &numOps);
/*
* For each operation that must be performed,
* construct a linked list for each of the
* struct integers in the file. Then, perform the operation
* indicated by the digit preceding them.
*/
for( i = 0; i < numOps; i++ )
{
// Read in the number that dictates operation
fscanf(inputFile, "%d", &oper);
// Read in the first struct integer into a string
fscanf(inputFile, "%s", bigintstr);
/*
* Pass the struct integer string to read_integer()
* in order to construct a linked list out of it.
*/
pHead = read_integer( bigintstr );
// Read in second struct integer into a string
fscanf(inputFile, "%s", bigintstr);
/*
* Pass the struct integer str to read_integer()
* in order to construct a linked list out of it.
*/
qHead = read_integer( bigintstr );
/*
* Depending on the operation to be performed,
* call the corresponding function.
*/
switch( oper )
{
case ADD:
tHead = add( pHead, qHead );
break;
case SUB:
tHead = subtract( pHead, qHead );
break;
default:
printf("Invalid operation parameter.\n");
}
print( pHead ); // Print out the first struct integer
fprintf(outFile, " + ");
print( qHead ); // Print out the second struct integer
fprintf(outFile, " = ");
print( tHead ); // Print out the sum/difference struct integer
fprintf(outFile, "\n"); // Move to next line for next instruction set
}
fclose(inputFile);
//system(PAUSE);
return 0;
}
// Function Definitions
/*
* Function read_integer
*
* @Parameter CHAR* stringInt
*
* Parameter contains a string representing a struct integer.
* Tokenizes the string by each character, converts each char
* into an integer, and constructs a backwards linked list out
* of the digits.
*
* @Return STRUCT* Integer
*/
struct integer* read_integer( char* stringInt )
{
int i, n;
struct integer *curr, *head;
int numDigits = strlen( stringInt ); // Find the length of the struct integer
char *tok;
head = NULL;
for( i = 0; i < numDigits; i++ )
{
tok = strtok( stringInt, NULL ); // Tokenize the string by each char
n = atoi( tok[i] ); // Convert char to an integer
curr = (struct integer *) malloc (sizeof( struct integer )); // Allocate memory for node
curr->digit = n; // Digit of current node is assigned to n
curr->next = head; // Move to the next node in the list.
head = curr; // Move head up to the front of the list.
}
return head; // Return a pointer to the first node in the list.
}
/*
* Function print
*
* @Parameter STRUCT* Integer
*
* Given a linked list, will traverse through
* the nodes and print out, one at a time,
* the digits comprising the struct integer that the
* linked list represents.
*
* TODO: Print to file
*/
void print( struct integer *p )
{
while( p )
{
fprintf(outFile, "%d", p->digit);
p = p->next;
}
}
/*
* Function add
*
* @Paramater STRUCT* Integer
* @Parameter STRUCT* Integer
*
* Takes two linked lists representing
* big integers stored in reversed order,
* and returns a linked list containing
* the sum of the two integers.
*
* @Return STRUCT* Integer
*
* TODO Comment me
*/
struct integer* add( struct integer *p, struct integer *q )
{
int carry = 0;
struct integer *sHead, *sCurr;
struct integer *pHead, *qHead;
pHead = p;
qHead = q;
sHead = NULL;
while( p )
{
sCurr = ( struct integer* ) malloc (sizeof(struct integer));
sCurr->digit = p->digit + q->digit + carry;
sCurr->next = sHead;
sHead = sCurr;
carry = 0;
/*
* If the current digits sum to greater than 9,
* create a carry value and replace the current
* value with value mod 10.
*/
if( sCurr->digit > 9 )
{
carry = 1;
sCurr->digit = sCurr->digit % 10;
}
/*
* If the most significant digits of the numbers
* sum to 10 or greater, create an extra node
* at the end of the sum list and assign it the
* value of 1.
*/
if( carry == 1 && sCurr->next == NULL )
{
struct integer *sCarry = ( struct integer* ) malloc (sizeof(struct integer));
sCarry->digit = 1;
sCarry->next = NULL;
sCurr->next = sCarry;
}
p = p->next;
q = q->next;
}
return sHead;
}
/*
* Function subtract
*
* @Parameter STRUCT* Integer
* @Parameter STRUCT* Integer
*
* Takes two linked lists representing struct integers.
* Traverses through the lists, subtracting each
* digits from the subsequent nodes to form a new
* struct integer, and then returns the newly formed
* linked list.
*
* @Return STRUCT* Integer
*
* TODO Comment me
*/
struct integer* subtract( struct integer *p, struct integer *q )
{
int carry = 0;
struct integer *dHead, *dCurr;
struct integer *pHead, *qHead;
pHead = p;
qHead = q;
dHead = NULL;
while( p )
{
dCurr = (struct integer*) malloc (sizeof(struct integer));
dCurr->digit = p->digit - q->digit - carry;
dCurr->next = dHead;
dHead = dCurr;
if( dCurr->digit < 0 )
{
dCurr->digit += 10;
carry = 1;
}
if( dCurr->next == NULL && carry == 1 )
{
struct integer *dCarry = (struct integer*) malloc (sizeof(struct integer));
dCarry->digit = -1;
dCarry->next = NULL;
dCurr->next = dCarry;
}
p = p->next;
q = q->next;
}
return dHead;
}
/*
* Function compare
*
* @Parameter STRUCT* Integer
* @Parameter STRUCT* Integer
*
* Takes in two linked lists representing struct integers.
* Traverses the lists one at a time, comparing the
* digits.
*
* Case: p < q
* @Return -1
*
* Case: p == q
* @Return 0
*
* Case: p > q
* @Return 1
*
* TODO Comment me
*/
int compare( struct integer *p, struct integer *q )
{
struct integer *pHead, *qHead;
int comp = 0;
pHead = p;
qHead = q;
while( p )
{
if( p->digit > q->digit )
{
comp = 1;
}
if( p->digit < q->digit )
{
comp = -1;
}
p = p->next;
q = q->next;
}
return comp;
}
很抱歉,有很多事情要处理,我只是想养成过度记录我的代码的习惯,因为我喜欢回去阅读我为审查概念而编写的内容。不过,实际程序本身相当简单(如果没有损坏,哈哈)。
【问题讨论】:
-
这里的代码太多,其他人可能会费心调试。将代码减少到尽可能小的东西。此外,使用 -g 标志编译您的代码,在 gdb 中运行它,并在它崩溃时发出
bt命令以获取堆栈跟踪。 -
我同意不,调试这么大的代码将是一项乏味的任务。
-
嗯,我试试看,谢谢。
-
分段错误意味着您取消了对无效指针的引用。在 gdb 或您使用的任何工具中运行它,您会立即找到它爆炸的那一行。
-
缺乏错误检查,尤其是在调用 malloc 时...良好的记录良好的代码-为此欢呼,太糟糕了,您没有检查 malloc 的返回值...仍然...很好代码! :)
标签: c segmentation-fault