簡體   English   中英

釋放內存分配

[英]Freeing Memory Allocation

我在弄清楚此錯誤的確切含義時遇到了麻煩。 它說:

map-test(29262,0x7fffb118e340) malloc: *** error for object 0x7fa5d7001000: pointer being freed was not allocated

但是,我很確定它已分配。 這里是有問題的功能。 我想可能是我弄亂了某個地方的記憶,但是我不認為是這種情況,但是我再次對其中一些東西感到陌生,而我的教授虔誠地(非常)地愛指針。 有人可以指引我正確的方向嗎? 提前謝謝了。

map.cpp

#include "map.hpp"
#include <string>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>

Map::Map() {
    database = new MapEntry*[DATABASE_SIZE];
    for (int i = 0; i < DATABASE_SIZE; i++){
        database[i] = new MapEntry("", 0);
    }
}

/* Adds (inserts) val with the associated key.
 * Returns if successful or not.  (It is not successful if we are out of
 * memory, or if the key already exists.)
 */
bool Map::add(const char *key, int val) {
    for (int i = 0; i < DATABASE_SIZE; i++)
        if (database[i]->getVal() == 0) {
            database[i]->setVal(val);
            database[i]->setKey(key);
            return true;
        }
    return false;
}

/* Searches for the key.  If found it sets ret to the correct val and
 * returns true.  Otherwise this function returns false.
 */
bool Map::get(const char *key, int &ret) {
    for (int i = 0; i < DATABASE_SIZE; i++){
        if (database[i]->getKey() == key) {
            ret = database[i]->getVal();
            return true;
        }
    }
    return false;
}

/* Returns the size (memory consumed) by this data structure. */
int Map::size() {
    int totalsize = 0;
    for (int i = 0; i < DATABASE_SIZE; i++){
        if (database[i]->getVal() != 0) {
            totalsize += sizeof(database[i]);
        }
    }
    return totalsize;
}

/* Removes the current value from the Map AND frees up any memory that it can.
 * Returns true if there was something to remove, false otherwise.
 */
bool Map::remove(const char *key) {
    for (int i = 0; i < DATABASE_SIZE; i++){
        if (database[i]->getKey() == key) {
            database[i]->setKey("");
            database[i]->setVal(0);
            return true;
        }
    }
    return false;
}

/* Returns the number of names with a given prefix.
 * EX: If we have {John, Jonathan, Paul, Mark, Luke, Joanna} then
 * howMany("Jo") == 3
 */
int Map::howMany(const char *prefix) {
    int count = 0;
    std::string beginning(prefix);
    for (int i = 0; i < DATABASE_SIZE; i++){
        std::string key(database[i]->getKey());
        if (key.substr(0, beginning.size()).compare(beginning) == 0) {
            count++;
        }
    }
    return count;
}

/* Frees all memory */
Map::~Map() {
for (int i = 0; i < DATABASE_SIZE; i++) {
        delete database[i];
    }
    delete[] database;
}

map.hpp

#ifndef MAP_H
#define MAP_H

const int DATABASE_SIZE = 1024;

class MapEntry{
    private:
        int mIDVal;
        const char* mKeyName;

    public:
        MapEntry(const char *key, int val) {
        mKeyName = key;
        mIDVal = val;
    }
    int getVal(){
        return mIDVal;
    }
    const char* getKey(){
        return mKeyName;
    }
    void setVal(int val){
        mIDVal = val;
    }
    void const setKey(const char* key){
        mKeyName = key;
    }
};

class Map{
    public:
        Map();

        bool add(const char *key, int val);

        void print();

        bool get(const char *key, int &ret);

        int size();

        bool remove(const char *key);

        int howMany(const char *prefix);

    ~Map();
private:
    MapEntry **database;
    Map(const Map &m){
        // Copy constructor in private to avoid double deleting.
    }
};

#endif

main.cpp

#include <stdlib.h>
#include <iostream>
#include "map.hpp"

using namespace std;

int main(int argc, char *argv[]) {
    Map myMap;
    myMap.add("Philip Fry", 51798);
    myMap.add("Turanga Leela", 987651234);
    myMap.add("Philip Fry", 89715);
    int pringles = 0;
    myMap.get("Philip Fry", pringles);
    cout << pringles << "\n";
    myMap.print();
    cout << myMap.size() << "\n";
    cout << "\n";
    myMap.remove("Philip Fry");
    myMap.print();
    pringles = 0;
    myMap.get("Philip Fry", pringles);
    cout << pringles << "\n";
    const char* prefix = "Phi";
    cout << myMap.howMany(prefix) << "\n";

    myMap.~Map();
    return 0;
}

當您直接調用析構函數時,您將在此處釋放內存。 您不應該手動調用析構函數。 當對象超出范圍時會自動調用它。 有您的雙重刪除。

myMap.~Map();  ///< this is wrong (get rid of it)

如果您需要直觀的證據證明析構函數被調用兩次,請對其進行修改以進行打印。

/* Frees all memory */
Map::~Map() {
    std::cout << "Map::~Map() invoked!" << std::endl;
    for (int i = 0; i < DATABASE_SIZE; i++) {
        delete database[i];
    }
    delete[] database;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM