我删除不正确吗?

时间:2018-01-26 04:29:19

标签: c++ arrays dynamic

因此在课堂上我们必须创建一个从文件中获取单词的代码,忽略标点符号并打印出单词。不仅如此,它还必须忽略同一个单词的副本,但要记录哪些单词重复并将其计数添加到并行数组。但是我一直在程序结束时崩溃,我是否错误地删除了?

#include <fstream>
#include <iostream>
#include <cstring>

using std::cout;
using std::cin;
using std::endl;
using std::ifstream;

int GetCount(char filename[50]);

int main()
{
    char filename[50] = "b.txt";
    int choice = 0;
    cout << "Input the file name: ";
    //cin >> filename;
    int numberOfWords = GetCount(filename);
    cout << endl << numberOfWords << endl;

    ifstream fileRead;
    cin.clear();
    cin.ignore(cin.rdbuf()->in_avail());
    fileRead.open(filename);
    if (!fileRead.is_open())
    {
        std::cerr << "\n Error opening file\n";
    }
    else
    {
        //Buffers to get words from file
        char buffer[1000];
        char bufferBuffer[1000];

我在这里声明了导致删除问题的数组

        //Array of pointers to words
        char ** cStringArray = new char *[numberOfWords];
        *cStringArray = nullptr;
        int add = 1; //Integer in case a word is repeated not to add

                     //Parrallel Array to integers
        int * intPtr = new int;
        *intPtr = 0;

        //Pointers used to check for repeated words
        int * startIntPtr = intPtr;
        int * checkIntPtr = startIntPtr;
        char ** startCStringArray = cStringArray;
        char ** checkCStringArray = cStringArray;

        //Index of Current Word
        int indexOfWord = 0;

        //Variables for character check
        int i = 0;
        int k = 0;

        //Loop to get words from file
        while (fileRead >> buffer)
        {
            //Add Word
            add = 1;

            //Copy only alpha characters
            i = 0;
            k = 0;
            while (buffer[k] != '\0')
            {
                if (isalpha(buffer[k]))
                {
                    bufferBuffer[i] = buffer[k];
                    i++;
                }
                k++;
            }
            bufferBuffer[i] = '\0';
            strcpy(buffer, bufferBuffer);


            //Actually set it in array
            *cStringArray = new char[strlen(buffer) + 1];
            strcpy(*cStringArray, buffer);

            //Compare Against all other cstrings
            for (int ii = 0; ii < indexOfWord; ii++)
            {
                if (strcmp(*checkCStringArray, buffer) == 0)
                {
                    *checkIntPtr += 1;
                    add = 0;
                }

                checkCStringArray++;
                checkIntPtr++;
            }

            //Reset Checks
            checkIntPtr = startIntPtr;
            checkCStringArray = startCStringArray;

            //Move onto next space of cStringArray
            if (add == 1)
            {
                cStringArray++;
                *cStringArray = nullptr;

                //Add one to index
                indexOfWord += 1;

                //Add one to intPtr
                *intPtr += 1;
                intPtr++;
                *intPtr = 0;
            }
            else
            {
                *cStringArray = nullptr;
                *intPtr = 0;
            }
        }
        cStringArray = startCStringArray;

        for (int i = 0; i < indexOfWord; i++)
        {
            cout << *cStringArray << endl;
            cStringArray++;
        }

        cStringArray = startCStringArray;
        intPtr = startIntPtr;

        for (int i = 0; i < indexOfWord + 1; i++)
        {
        cStringArray[i] = nullptr;
        delete[] cStringArray[i];
        }
        cStringArray = startCStringArray;

在这一行打破

    delete [] cStringArray;
    /*delete[] intPtr;*/
}
return 0;
}

1 个答案:

答案 0 :(得分:4)

每个new必须与delete配对。我们来检查一下吗?

char ** cStringArray = new char *[numberOfWords];

配对
delete [] cStringArray;

Groovy的。

*cStringArray = new char[strlen(buffer) + 1];

配对
delete[] cStringArray[i];

一切看起来都不错。

除了......

让我们看看最后一个有更多背景的人。

for (int i = 0; i < indexOfWord + 1; i++)
{
    cStringArray[i] = nullptr;
    delete[] cStringArray[i];
}

Hmmmm。将指针设置为nullptr。删除nullptr。在删除之前,程序丢失了指针并泄漏了内存。

近距离观察不太好,周围噪音较少。

请注意,这只是查看删除。我还没有看到代码中可能存在的其他问题。乍一看,它似乎过于复杂。这就是Minimal, Complete, and Verifiable example如此有用的原因。如果你把所有不必要的东西都砍掉了,那就会让错误更加突出。