【发布时间】:2015-09-28 21:07:32
【问题描述】:
我有以下结构:
class List{
public: //Functions go here
typedef struct node{
string data;
node* prev;
node* next;
}* nodePtr;
nodePtr head;
nodePtr curr;
nodePtr temp;
nodePtr tail;
List();
//~List();
void addToEnd(string addData);
void addToBeg(string addData);
void DeleteList();
//More functions not included//
};
带有构造函数:
List::List(){
head = NULL;
curr = NULL;
temp = NULL;
tail = NULL;
}
并删除节点:
void List::DeleteList(){
temp = head;
curr = head;
while(curr != NULL){
temp = curr->next;
delete curr;
curr = temp;
}
}
其余代码接受数字并通过将数字划分为节点来对它们进行加法和乘法运算。我在每个列表的每个函数的末尾调用 DeleteList()。当我使用 Valgrind 运行代码时,我的输出以正确的答案完成,即使它在一些函数调用上显示“条件跳转或移动取决于未初始化的值”。
当我使用 gcc 执行程序时,我得到一个“被释放的指针没有被分配”。两种执行方式有什么区别?为什么 gcc 说指针没有分配?
添加节点如下所示:
void List::addToEnd(string addData){ //adds to end of linked list
//nodePtr n = (nodePtr)malloc(sizeof(node));
nodePtr n = new node;
n->next = NULL;
n->data = addData;
if(head != NULL){
curr = head;
while(curr->next != NULL){
curr = curr->next;
}
curr->next = n;
n->prev = curr;
tail = n;
}
else{
n->prev = NULL;
head = n;
tail = n;
}
}
编辑:完整代码供参考:
//structure for assembling doubly linked list.
#include <cstdlib>
#include <iostream>
#include <stdlib.h>
#include <cstring>
#include <string.h>
#include <math.h>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
using namespace std;
class List{
public: //Functions go here
typedef struct node{
string data;
node* prev;
node* next;
}* nodePtr;
nodePtr head;
nodePtr curr;
nodePtr temp;
nodePtr tail;
List();
~List();
void addToEnd(string addData);
void addToBeg(string addData);
List::nodePtr returnHead();
List::nodePtr returnNext(List::nodePtr n);
List::nodePtr returnPrev(List::nodePtr n);
List::nodePtr returnTail();
void DeleteList();
void PrintList();
void ConvertHead();
void DeleteNode(string delData);
string ListValue();
string returnValue(List::nodePtr n);
};
//Functions
List addLists(List a, List b, long long nodeLength);
List multLists(List a, List b, long long nodeLength);
string doArithmetic(string num1, string num2, string op, long long nodSiz);
string removeSpaces(string input);
int main(int argc, char** argv){
string sentence, sent2, operation, arg1, arg2;
long long digitCount;
int op;
//Takes in the first argument and finds the first double quote
//Uses what is in the quotes as the filename
string str (argv[1]);
size_t firstEqual = 6;
size_t semicolon = str.find_first_of(";");
size_t secondEqual = semicolon + 17;
std::string file = str.substr(firstEqual, semicolon - firstEqual);
digitCount = stoll(str.substr(secondEqual, str.length()));
//Opens the file designated in the argument
ifstream inputFile (file.c_str());
while(getline(inputFile, sentence)){
sent2 = removeSpaces(sentence);
op = sent2.find_first_of("+*");
arg1 = sent2.substr(0,op);
arg2 = sent2.substr(op+1,string::npos);
//cout << "arg1: " << arg1 << " arg2: " << arg2 << " Operation: " << sent2.substr(op,1) << endl;
cout << sent2 << "=";
cout << doArithmetic(arg1, arg2, sent2.substr(op,1), digitCount) << endl;
}
return 0;
}
string doArithmetic(string num1, string num2, string op, long long nodSiz){
long long nodeSize = nodSiz;
string numberOne = num1; //14
string numberTwo = num2;
string answer;
List value1, value2, result;
//cout << numberOne << endl;
//assigns values as strings to value1
if(strlen(numberOne.c_str())%nodeSize != 0){
value1.addToEnd(numberOne.substr(0,strlen(numberOne.c_str())%nodeSize));
for(int i=0; i < strlen(numberOne.c_str())/nodeSize; i++){
value1.addToEnd(numberOne.substr(strlen(numberOne.c_str())%nodeSize + i*nodeSize,nodeSize));
}
}
else{
for(int i=0; i < strlen(numberOne.c_str())/nodeSize; i++){
value1.addToEnd(numberOne.substr(strlen(numberOne.c_str())%nodeSize + i*nodeSize,nodeSize));
}
}
//value1.PrintList();
//cout <<numberTwo<<endl;
//assigns values as strings to value2
if(strlen(numberTwo.c_str())%nodeSize != 0){
value2.addToEnd(numberTwo.substr(0,strlen(numberTwo.c_str())%nodeSize));
for(int i=0; i < strlen(numberTwo.c_str())/nodeSize; i++){
value2.addToEnd(numberTwo.substr(strlen(numberTwo.c_str())%nodeSize + i*nodeSize,nodeSize));
}
}
else{
for(int i=0; i < strlen(numberTwo.c_str())/nodeSize; i++){
value2.addToEnd(numberTwo.substr(strlen(numberTwo.c_str())%nodeSize + i*nodeSize,nodeSize));
}
}
//value2.PrintList();
if(op == "+"){
result = addLists(value1, value2, nodeSize);
}
else{
result = multLists(value1, value2, nodeSize);
}
result.ConvertHead();
answer = result.ListValue();
value1.DeleteList();
value2.DeleteList();
result.DeleteList();
return answer;
}
List multLists(List a, List b, long long nodeLength){
List n;
List::nodePtr aPoint, bPoint;
long long valueA, valueB, product;
long long leftover = 0;
string filler;
long long lengthDiff;
int counterA = 0;
int counterB = 0;
for(int i=0; i < nodeLength;i++) filler = "0" + filler;
bPoint = b.returnTail();
while(bPoint != NULL){
//cout << "B Point" << endl;
valueB = stoll(b.returnValue(bPoint));
leftover = 0;
aPoint = a.returnTail();
counterA = 0;
while(aPoint != NULL){
//cout << "A Point" << endl;
List temp;
valueA = stoll(a.returnValue(aPoint));
product = valueA * valueB + leftover;
lengthDiff = to_string(product).length() - nodeLength;
if(to_string(product).length() > nodeLength){
temp.addToBeg(to_string(product).substr(to_string(product).length()-nodeLength,nodeLength));
leftover = stoll(to_string(product).substr(0,lengthDiff));
}
else{
temp.addToBeg(to_string(product));
leftover = 0;
}
for(int i = 0; i < counterA + counterB; i++){
temp.addToEnd(filler);
}
n = addLists(n,temp,nodeLength);
temp.DeleteList();
aPoint = a.returnPrev(aPoint);
counterA = counterA + 1;
}
bPoint = b.returnPrev(bPoint);
counterB = counterB + 1;
}
if(leftover != 0) n.addToBeg(to_string(leftover));
return n;
}
List addLists(List a, List b, long long nodeLength){
List n;
List::nodePtr aPoint, bPoint;
long long valueA, valueB, sum;
long long leftover = 0;
long long lengthDiff;
string input;
aPoint = a.returnTail();
bPoint = b.returnTail();
while(aPoint != NULL || bPoint != NULL){
if(aPoint != NULL) valueA = stoll(a.returnValue(aPoint));
else valueA = 0;
if(bPoint != NULL) valueB = stoll(b.returnValue(bPoint));
else valueB = 0;
sum = valueA + valueB + leftover;
if(to_string(sum).length() > nodeLength){
input = to_string(sum).substr(to_string(sum).length()-nodeLength,nodeLength);
}
else {
input = to_string(sum);
}
lengthDiff = nodeLength-to_string(sum).length();
if(nodeLength > to_string(sum).length()){
for(int i=0; i < nodeLength-to_string(sum).length();i++){
// cout << "sumLength: " << to_string(sum).length() << endl;
input = "0" + input;
}
}
n.addToBeg(input);
if(to_string(sum).length() > nodeLength){
leftover = stoll(to_string(sum).substr(0,to_string(sum).length() - nodeLength));
}
else leftover = 0;
if(aPoint != NULL) aPoint = a.returnPrev(aPoint);
if(bPoint != NULL) bPoint = b.returnPrev(bPoint);
// cout << "sum: " << sum << " sum.length(): " << to_string(sum).length() << " leftover: " << leftover << endl;
// cout << "lengthDiff: " << to_string(sum).substr(0,to_string(sum).length() - nodeLength) << endl;
}
if(leftover != 0) n.addToBeg(to_string(leftover));
return n;
}
List::List(){
head = NULL;
curr = NULL;
temp = NULL;
tail = NULL;
}
List::~List(){
temp = head;
curr = head;
while(curr != NULL){
temp = curr->next;
delete curr;
//free(curr);
curr = temp;
}
head = curr = temp = tail = NULL;
}
void List::addToEnd(string addData){ //adds to end of linked list
//nodePtr n = (nodePtr)malloc(sizeof(node));
nodePtr n = new node;
n->next = NULL;
n->data = addData;
if(head != NULL){
curr = head;
while(curr->next != NULL){
curr = curr->next;
}
curr->next = n;
n->prev = curr;
tail = n;
}
else{
n->prev = NULL;
head = n;
tail = n;
}
}
void List::addToBeg(string addData){ //adds to beginning of linked list
//nodePtr n = (nodePtr)malloc(sizeof(node));
nodePtr n = new node;
n->prev = NULL;
n->data = addData;
if(head != NULL){
curr = head;
while(curr->prev!= NULL){
curr = curr->prev;
}
curr->prev = n;
n->next = curr;
head = n;
}
else{
n->prev = NULL;
head = n;
tail = n;
}
}
List::nodePtr List::returnHead(){
return head;
}
List::nodePtr List::returnNext(List::nodePtr n){
return n->next;
}
List::nodePtr List::returnPrev(List::nodePtr n){
return n->prev;
}
List::nodePtr List::returnTail(){
return tail;
}
string List::returnValue(List::nodePtr n){
return n->data;
}
void List::DeleteList(){
temp = head;
curr = head;
while(curr != NULL){
temp = curr->next;
delete curr;
//free(curr);
curr = temp;
}
head = curr = tail = temp = NULL;
}
void List::ConvertHead(){
long long convert;
curr = head;
convert = stoll(curr->data);
curr->data = to_string(convert);
}
void List::PrintList(){
curr = head;
while(curr != NULL){
cout << curr->data << endl;
curr = curr->next;
}
}
string List::ListValue(){
string value;
curr = head;
while(curr != NULL){
value = value + curr->data;
curr = curr->next;
}
return value;
}
string removeSpaces(string input){ //found on cplusplus.com
int length = input.length();
for (int i = 0; i < length; i++) {
if(input[i] == ' ') input.erase(i, 1);
}
return input;
}
命令行提示示例:
./a.out "input=test0.txt; digitsPerNode =3"
带有名为 test0.txt 的示例输入文件:
0*0
0+1
2*3
2*2000000000000000
2*3
1+10
10000000000000000+1
12345667890123456789 + 8765432109876543210
999999999999999999999 + 1
【问题讨论】:
-
发布一个完整但最小的例子,读者可以尝试。
-
你指的是什么析构函数?我在这段代码中没有看到任何析构函数。
-
代码中的析构函数被注释掉了。
-
在调用
DeleteList()后,您是否重复使用相同的List对象?它使对象处于不一致的状态。之后不能为该对象调用其他函数。要重用对象DeleteList(),必须重置所有指针head = curr = tail = temp = NULL。 -
当你“使用 gcc 执行程序”时?您使用 gcc 构建可执行文件,然后自行运行可执行文件。 gcc 真的告诉你一个未分配的指针正在被释放吗?这听起来像是一个运行时错误,所以要么 1) 其他东西告诉你,2) gcc 告诉你其他东西,或者 3) gcc 比我想象的更聪明。请给我们minimal complete example,这样我们就可以停止猜测了。