使用动态内存可能导致内存泄漏?

时间:2017-07-20 02:19:25

标签: c++ memory-leaks dynamic-memory-allocation

在这个程序中,我编写了一个名称列表,特别是使用指针,并在列表上执行冒泡排序和二进制搜索。我认识到有更好的方法来处理这种类型的记忆,但我希望在继续之前正确地学习这种方式。我没有正确解除分配和/或分配内存时遇到错误,但是现在,我没有弹出运行此代码的任何错误消息,但我仍然认为某些内存未正确解除分配。这是我的代码:

Main.cpp的

#include "Functions.h"
void main() {
     // initialize variables
     int numNames = 0;
     char* search;
     int index = 0;
     bool isSearching = true;
     // get list of names
     cout << "Enter your list of names:" << endl;
     char** nameList = readList(numNames);
     // sort list of names
     bubbleSort(nameList, numNames);
     // show sorted list of names
     cout << "Sorted list of names:" << endl;
     for (int i = 0; i < numNames; i++) {
         cout << nameList[i] << endl;
     }
     // do binary search loop
     do {
         // get search word
         cout << "Enter a word you would like to search for: " << endl;
         search = readLine();
         // get index of search
         index = binarySearch(nameList, numNames, search);
         // if missing
         if (index == -1) {
             cout << "That word is missing" << endl;
         }
         // show index
         else {
            cout << "That word is at index " << index << endl;
         }
         // set loop test
         isSearching = search[0] != '\0';
         // free mem
        delete[] search;
     } while (isSearching);
     // free mem
     for (int i = 0; i < numNames; i++) {
        delete[] nameList[i];
     }
     delete[] nameList;
     system("Pause");
}

Functions.h

#ifndef FUNCTIONS_H
#define FUNCTIONS_H

#include "ReadFunctions.h"
#include "SortingAndSearchingFunctions.h"

#endif

ReadFunctions.h

#ifndef READ_FUNCTIONS_H
#define READ_FUNCTIONS_H

#include <iostream>
#include <conio.h>
#include <memory.h>
#include "Functions.h"

using namespace std;

char* readLine();
char** readList(int &);

#endif

ReadFunctions.cpp(之前的readList函数遇到了问题,虽然错误没有弹出,但我仍然认为可能存在内存泄漏。)

#include "ReadFunctions.h"

static void backspace() {
    _putch('\b');
    _putch(' ');
}

char** readList(int & numWords) { // read list of words
    // initialize variables
    const int firstNumWords = 10;
    char* word;
    numWords = 0;
    int maxWords = firstNumWords;
    char** wordList = new char*[maxWords];
    char** temp;
    // read list loop
    while ((word = readLine())[0] != '\0') {
        // add word
        wordList[numWords++] = word;
        // expand list
        if (numWords >= maxWords) {
            maxWords += firstNumWords;
            temp = new char*[maxWords];
            memcpy(temp, wordList, numWords * sizeof(char*));
            wordList = temp; 
            //may need delete statement?
        }
    }
    return wordList;
}

char* readLine() { // read word
    // initialize variables
    const int firstNumChar = 10;
    char c;
    int charsEntered = 0;
    int maxChars = firstNumChar;
    char* word = new char[maxChars + 1];
    char* temp;
    cout << "> ";
    // read word loop
    while ((c = _getch()) != '\r') {
        // backspace
        if (c == '\b') {
            if (charsEntered == 0) {
                c = '\a';
            }
            else {
                backspace();
                charsEntered--;
                word[charsEntered] = '\0';
            }
        }
        else {
            // add character
            word[charsEntered++] = c;
            // expand word
            if (charsEntered >= maxChars) {
                maxChars += firstNumChar;
                temp = new char[maxChars + 1];
                memcpy(temp, word, charsEntered);
                delete[] word;
                word = temp;
            }
        }
        _putch(c);
    }
    _putch('\n');
    word[charsEntered] = '\0';
    return word;
}

SortingAndSearchingFunctions.h

#ifndef SORTING_AND_SEARCHING_FUNCTIONS_H
#define SORTING_AND_SEARCHING_FUNCTIONS_H

#include "Functions.h"
#include <string.h>

void bubbleSort(char** &, int);
int binarySearch(char** &, int, char*);

#endif

SortingAndSearchingFunctions.cpp

#include "SortingAndSearchingFunctions.h"

static bool isAfter(char* str1, char* str2) { // check if first string is after the second string
    // initialize variables
    bool isGreater = false;
    bool isEqual = false;
    char c1;
    char c2;
    int compareLen = (strlen(str1) >= strlen(str2)) ? strlen(str2) : strlen(str1);
    // check c-strings
    for (int i = 0; i < compareLen; i++) {
        // get compare characters
        c1 = str1[i];
        c2 = str2[i];
        // check if both alphabetical
        if (((c1 >= 'a' && c1 <= 'z') || (c1 >= 'A' && c1 <= 'Z')) && ((c2 >= 'a' && c2 <= 'z') || (c2 >= 'A' && c2 <= 'Z'))) {
            // normalize for case insensitive
            if (c1 >= 'A' && c1 <= 'Z') {
                c1 = (char)(c1 + 32);
            }
            else if (c2 >= 'A' && c2 <= 'Z') {
                c2 = (char)(c2 + 32);
            }
        }
        // handle comes after
        if (c1 > c2) {
            isGreater = true;
            isEqual = false;
            i = compareLen;
        }
        // handle comes before
        else if (c1 < c2) {
            isGreater = false;
            isEqual = false;
            i = compareLen;
        }
        // handle equal
        else {
            isEqual = true;
        }
        // case with symbol, which case to compare with?
    }
    // handle equal comparison region
    if (isEqual) {
        if (strlen(str1) > strlen(str2)) {
            isGreater = true;
        }
    }
    return isGreater;
}

void bubbleSort(char** & wordList, int numWords) { // bubble sort for word lists
    // initialize variables
    char* temp;
    bool swap = false;
    // sort loop
    do {
        // set swap and numwords
        swap = false;
        numWords--;
        // check list
        for (int i = 0; i < numWords; i++) {
            // swap
            if (isAfter(wordList[i], wordList[i + 1])) {
                swap = true;
                temp = new char[((strlen(wordList[i]) >= strlen(wordList[i + 1])) ? strlen(wordList[i + 1]) : strlen(wordList[i])) + 1];
                memcpy(temp, wordList[i], strlen(wordList[i]) + 1);
                //temp = wordList[i];
                memcpy(wordList[i], wordList[i + 1], strlen(wordList[i + 1]) + 1);
                //wordList[i] = wordList[i + 1];
                memcpy(wordList[i + 1], temp, strlen(temp) + 1);
                //wordList[i + 1] = temp;
                //delete[] temp; // if included shows access violation, but should still include and find another way? 
            }
        }
    } while (swap);
}

int binarySearch(char** & wordList, int numWords, char* search) { // binary search for word lists
    // initialize variables
    int first = 0;
    int mid;
    int last = numWords - 1;
    // search loop
    do {
        // set middle index
        mid = (first + last) / 2;
        // check if equal
        if (strcmp(search, wordList[mid]) == 0) {
            return mid;
        }
        // check if after
        else if (isAfter(search, wordList[mid])) {
            first = mid + 1;
        }
        // check if before
        else {
            last = mid - 1;
        }
    } while (first <= last);
    // not found
    return -1;
}

如果您没有发现任何问题,是否有任何方法可以正确设置动态内存并检查内存泄漏,以便我不会担心此问题。

编辑:这是ReadFunctions.cpp文件中readList函数中while循环中代码的修改版本:

// add word
    wordList[numWords++] = word;
    // expand list
    if (numWords >= maxWords) {
        maxWords += firstNumWords;
        temp = new char*[maxWords];
        memcpy(temp, wordList, numWords * sizeof(char*));
        delete[] wordList;
        wordList = temp; 
    }

1 个答案:

答案 0 :(得分:0)

什么阻止您使用std::vectorstd::string?这将消除所有内存泄漏,使代码更有效,并减少代码的大小相当多。使用std::sort也有助于减少不必要的代码复杂性。

你需要围绕//may need delete statement?评论发送一个delete []声明。

您的修改后的代码不起作用,因为:

if (numWords >= maxWords) {
    maxWords += firstNumWords;
    temp = new char*[maxWords];
    for (int i = 0; i < numWords; i++) {       // you're copying into uninititialized pointers !!!!!
        memcpy(temp[i], wordList[i], (strlen(wordList[i]) + 1) * sizeof(char));
    }
    for (int i = 0; i < numWords; i++) {
        delete[] wordList[i];
    }
    wordList = temp; 
}

调整指针数组大小的正确方法:

if (numWords >= maxWords) {
    temp = new char*[maxWords + firstNumWords];        // allocate new array
    memcpy(temp, wordList, maxWords * sizeof(char*));  // copy the pointer values.
    char* p = wordList;
    wordList = temp;                                   // put new array in place.
    delete[] p;                                        // delete old array.
    maxWords += firstNumWords;                         // fix size var.
}