调试断言失败!使用指针运算的字符串操作

Debug Assertion Failed! String manipulation using pointer arithmetic

本文关键字:运算 字符串 操作 指针 断言 失败 调试      更新时间:2023-10-16

EDIT: Pastebin链接到底部的完整代码

在我的CS215课程中,我有一个叫做String215的类,这是一个基本的字符串类,帮助我理解动态内存分配和char数组的指针运算。

这个类是以一个非常基本的骨架形式提供给我的,有原型,但没有实现,还有一个测试函数来测试我的实现。我不能在这个赋值中使用任何C字符串函数。

程序中出现问题的部分是append函数,它只是将一个参数string215对象追加到当前string215对象的末尾。

// Add a suffix to the end of this string.  Allocates and frees memory.
void string215::append(const string215 &suffix)
{
    char *output = new char[str_len(data)+suffix.length()+1];
    for(int x = 0; x < str_len(data); x++) {
            *output = *data;
        output++;
        data++;
    }
    for(int x = 0; x < suffix.length(); x++) {
        *output = suffix.getchar(x);
        output++;
    }
    *output = '';
    output -= (str_len(data)+suffix.length()+1);
    delete[] data;
    data = output;
}

这部分代码在test函数的第13次测试中进行测试,如下所示:

string215 str("testing");
...
// Test 13: test that append works in a simple case.
curr_test++;
string215 suffix("123");
str.append(suffix);
if (strcmp(str.c_str(), "testing123") != 0) {
    cerr << "Test " << curr_test << " failed." << endl;
    failed++;
}

下面是附加类的描述:

在该字符串的末尾添加后缀。分配一个新的更大的数组;将旧的内容(后跟后缀)复制到新数组;然后释放旧数组并更新指针到新数组。

我的程序在append函数执行的最后终止,并显示错误消息:

Debug Assertion Failed!
Program: [Source path]dbgdel.cpp
Line: 52
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
...
Abort || Retry || Ignore

我相当确定这与我非常糟糕的内存管理有关。我知道这没什么可说的,但我已经连续几个小时纠结这个问题了,似乎还是想不明白。

下面是这个程序的。cpp和。h文件的粘贴目录

string215.cpp: http://pastebin.com/Xh2SvDKJ

string215.h: http://pastebin.com/JfAJDEVN

任何帮助都是非常感激的!

谢谢,RAW-BERRY

delete[]之前更改data指针。你需要delete[]与你从new[]得到的值完全相同。

同样,您正在增加output指针str_len(data)+suffix.length()次,并通过str_len(data) + suffix.length() + 1将其收回。

我会使用单独的变量进行迭代来解决这些问题。

output正好增加str_len(data) + suffix.length()倍。注意,*output = '';之后不能增加output

要返回到开始,你应该使用:

output -= (str_len(data) + suffix.length());
顺便说一下,有些代码不是很有效。例如,getchar使用循环而不是简单地返回data[index]。您在append中使用getchar,这意味着性能不是很好。

EDIT:正如zch所说,您在修改data之后使用delete[] data,但请注意,即使在此之前,您在修改data之后使用str_len(data)(在决定要跳回多少字节时),因此计算是错误的(我上面的建议也是错误的,因为str_len(data)现在是零)。

所以我认为你的问题出在

这一行
for(int x = 0; x < str_len(data); x++) {

注意'data'的大小在循环的每次迭代中都在变化。当你增加'x'时,你正在减少'data'的长度。假设'data'是一个包含"hello"的字符串:在循环的第一次迭代中x=0 and str_len(data)=5;在第二次迭代中,x=1, str_len(data)=4。因此,for循环执行的次数是您需要的一半,并且'data'最终不会指向数据字符串

的末尾。