【发布时间】:2014-09-22 01:42:56
【问题描述】:
所以我正在尝试完成这个非常基本的字符串类(MyString)。一切似乎都正常,但是当我将其上传到作业站点时,它显示了一个段错误。上传网站使用了电围栏,但并没有提供太多关于故障发生位置的信息。它基本上贯穿每个函数并为其返回通过/失败/错误。对于getline 函数,它返回了一个错误。
另外,上传网站使用 valgrind 没有报告错误。
编辑:我差点忘了,当我在驱动程序中调用该函数时,它从文件messages.txt 中读取,其中包含一行文本:Testing this program... PLEASE WORK
下面是getline 函数(因为它存在于实现文件中),它似乎是错误的根源:
// reads line from istream ... line end at newline char of choice) -- '\n' in this case
void MyString::getline(istream &inFile, char delimit)
{
int index = 0;
do
{
data[index] = inFile.get();
index ++;
if (index + 1 > capacity)
{
MyString tempStr;
delete [] tempStr.data;
tempStr.data = new char [capacity];
for (int i = 0; i <= index; i++)
{
tempStr.data[i] = data[i];
}
capacity += 5;
size = index;
delete [] data;
data = new char [capacity];
for (int i = 0; i <= size; i++)
{
data[i] = tempStr.data[i];
}
delete [] tempStr.data;
tempStr.data = NULL;
}
}
while (!inFile.eof() && data[index-1] != delimit);
if (data[index - 1] == delimit)
{
index -= 1;
if (static_cast<double>(index)/capacity < .25 && capacity > 5)
{
capacity -= 5;
char *temp = new char [capacity];
for (int i = 0; i < index; i++)
{
temp[i] = data[i];
}
delete [] data;
data = temp;
}
}
data[index] = '\0';
size = index + 1;
}
我觉得要么是我忽略了一些非常简单的事情,要么是我处理这个特定功能的方式中的一个根本缺陷。任何帮助表示赞赏。我对编程非常陌生(几周后),我只是想维持生计——同时注册了 CompSci 1 + 2。
此外,下面是更多的实现文件——特别是构造函数(减去副本)和一些重载的运算符。虽然我可以最终编译它并成功连接类对象,但上传站点在测试“连接”时返回失败。没有任何关于哪个操作员失败的反馈。我很好奇我的代码中可能导致这种情况的原因。再次感谢。
#include <iostream>
#include <fstream>
#include "MyString.h"
using namespace std;
//default constructor - works
MyString::MyString()
{
capacity = 5;
size = 0;
data = new char [capacity];
}
// constructor with character string
MyString::MyString(const char *cString)
{
int index = 0;
capacity = 5;
while ( cString[index] != '\0')
{
index++;
}
size = index + 1;
while (size > capacity)
{
capacity += 5;
}
data = new char[capacity];
for (int i = 0; i < size; i++)
{
data[i] = cString[i];
}
}
// copy constructor
MyString::MyString(const MyString &aMyString)
{
capacity = aMyString.capacity;
size = aMyString.size;
data = new char [capacity];
for (int i = 0; i < size; i++)
{
data[i] = aMyString.data[i];
}
}
// overloaded += operator
void MyString::operator+=(const MyString &aMyString)
{
int tSize1 = size;
int holder = 0;
size += aMyString.size - 1;
while (size > capacity)
{
capacity += 5;
}
char *tempArr = new char [capacity];
for (int i = 0; i < (tSize1 - 1); i ++)
{
tempArr[i] = data[i];
}
for (int i = (tSize1 - 1); i < size; i++)
{
tempArr[i] = aMyString.data[holder];
holder ++;
}
delete [] data;
data = tempArr;
}
// overloaded + operator
MyString MyString::operator+(const MyString &aMyString) const
{
int holder = 0;
MyString tempS;
int tSize1 = size + aMyString.size - 1;
int tCap1 = capacity + aMyString.capacity;
if (static_cast<double>(tSize1)/tCap1 < .25 && tCap1 > 5)
{
tCap1 -= 5;
}
tempS.size = tSize1;
tempS.capacity = tCap1;
delete [] tempS.data;
tempS.data = new char [tempS.capacity];
for (int i = 0; i < (size - 1); i ++)
{
tempS.data[i] = data[i];
}
for (int i = (size - 1); i < tSize1; i++)
{
tempS.data[i] = aMyString.data[holder];
holder ++;
}
return tempS;
}
【问题讨论】:
-
那是很多代码。你为什么不跟踪并找出它在哪里出现了段错误,然后问我们为什么......你可以使用调试器(gdb、Visual Studio 等)进行跟踪,或者使用 printf 添加跟踪消息。
-
你还没有定义复制构造函数。
-
这可能不会导致您的段错误,但您的代码有
while (!eof)反模式的变体。您需要检查流是否在读取后失败但之前对提取的值进行任何操作。 -
您使用什么开发环境进行编程? (操作系统/编译器等)
-
我目前正在使用代码块(如大学推荐的那样)并在 Windows 7 中这样做。
标签: c++ string segmentation-fault getline dynamic-arrays