c++ - 删除已声明为新的指针时出错?

标签 c++ pointers memory-management

我现在正在编写一个程序,它使用指向字符串的指针来更改 C_String。我有一个运行良好的实现。我遇到的唯一问题是,当我到达程序末尾时,如果我尝试删除指针,则会出现错误。

我的代码:

void CStringSwitcher()
{

    string input = "";
    char* cStringArray = new char[ASIZE];
    char* reversed = new char[ASIZE];
    const char* originalReversed = reversed;
    char* pointers[POINTER_SIZE];
    memset(reversed, '\0', ASIZE);
    memset(cStringArray, '\0', ASIZE);
    memset(pointers, '\0', POINTER_SIZE);
    char* current = cStringArray;
    cout << "Enter a sentence on each line. Input a 0 to stop." << endl;

    // Receives input from the user and stores it into cStringArray
    int i = 0;
    do
    {
        cout << ">";
        cin.clear();
        fflush(stdin);
        input = "";
        getline(cin, input);
        if (input == "0")
            break;
        else
        {
            input.append("\n");
            pointers[i] = current;
            _CRT_SECURE_STRCPY(pointers[i], ASIZE - 1, input.c_str());
            current += input.length();
            i++;
        }
    } while(i < POINTER_SIZE);
    char* end = current;

    --i;
    do
    {
        /// Check if done
        if(i < 0)
            break;
        /// Copy from current to end
        current = pointers[i];
        do
        {

            *reversed++ = *current++;
        }while(current < end);
        /// Update end
        end = pointers[i];
        /// Update i
        --i;
    }while(true);
    *reversed = '\0';
    cout << endl << originalReversed << endl;
    system("PAUSE");
    //delete[] originalReversed;
    //delete[] cStringArray;
    return;
}

正如上面所写,代码工作正常,但是如果我在返回之前取消注释两个删除行,我会收到错误消息:

Project_06.exe has initiated a breakpoint

然后程序崩溃了。奇怪的是我只是再次运行该程序以获取错误消息的确切措辞并且它运行时没有错误?关于为什么会这样有什么想法吗?

最佳答案

我猜这段代码是一个教育/实践文章,试图巩固您对指针的了解,但坦率地说:读起来绝对令人恐惧。

这个回答本着“授人以渔”的精神。

首先删除所有分配,改用固定大小的数组。

char cStringArray[ASIZE] = "";
char reversed[ASIZE] = "";

这暂时消除了对 memset 的需要,这个赋值实际上将整个数组设置为 0(参见 http://ideone.com/WmLtQp)。

这样做可以在通过调试器运行时更​​容易捕获损坏。

然后将数组切换为动态分配。

最后,不要混用 stdin 和 cin,这样做会引发未定义的行为。

---- 编辑----

这是您代码的 C++ 重构。这篇文章展示了如何手动完成(手动复制字节)和使用 C++ 功能来减少我们必须自己完成的工作量。

ideone 现场演示:http://ideone.com/0KuGiB

#include <iostream>
#include <string>
#include <vector>

void CStringSwitcher()
{
    std::vector<std::string> inputs;
    size_t totalLength = 0;

    std::cout << "Enter a sentence on each line. Input a 0 to stop." << std::endl;
    inputs.reserve(16);

    for ( ; /* until break */ ; ) {
        std::cout << ">";
        std::string input;
        getline(std::cin, input);
        if (input == "0")
            break;
        inputs.push_back(input);
        totalLength += input.length() + 1; // for the '\n'
    }

    std::string reversed = "";
    reversed.reserve(totalLength); // eliminate allocations

    // walk backwards thru the list of strings.
    for (auto inputsIt = inputs.rbegin(); inputsIt != inputs.rend(); ++inputsIt) {
        const std::string& input = *(inputsIt);

#ifndef REAL_CODE
        // educational, Do-It-Yourself way
        const size_t length = input.length();

        // walk backwards thru the characters
        for (size_t i = 0; i < length; ++i) {
            reversed += input[length - 1 - i];
        }
#else
        // call append with reversed iterators to do it for us.
        reversed.append(input.rbegin(), input.rend());
#endif

        // add the trailing '\n'
        reversed += '\n';
    }

    std::cout << std::endl << reversed << std::endl;

    // don't pause, set a break point at the end of the function
    // or run without debugging.

    return;
}

int main(int argc, const char* argv[])
{
    CStringSwitcher();

    return 0;
}

关于c++ - 删除已声明为新的指针时出错?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19893293/

相关文章:

c++ - 运行 Opencl 时出现异常

c++ - 如何使用 C++ 套接字库

c - 尝试在模拟操作系统内存管理器中显示分配内存的 "map"

java - 如何从命令行检查正在运行的 JVM 的堆使用情况?

c - 释放数据时内存泄漏?

c++ - 使用过剩加载 ppm 文件

c++ - 在实现 operator[] 时,我应该如何包括边界检查?

c - 使用指针的结构会出错

c - 如何在运行时创建单链表并对其进行排序?

c - 在 C 结束时从指针位置读取十六进制输出