My assignment is to make a program that can resize a dynamically allocated array. But when I delete a value, the program crashes (memory leak?). Here's my code.

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <limits>
using namespace std;

typedef char* charPtr;
typedef charPtr* strPtr;

strPtr delEntry(strPtr a, int &size, charPtr str);
charPtr getStr();
void printMenu();
char getch();
void resize(strPtr &a, int &size, int new_size);
void delStr(strPtr a, int pos, int size);
int search(strPtr a, int size, charPtr str);

int main() {
    strPtr a;
    char ch;
    charPtr str;
    int size = 5;
    a = new charPtr[size];

    str = new char[80];
    for (int i = 0; i < size; i++)
        a[i] = new char[80];

    cout << "Enter five names." << endl;
    for (int i = 0; i < size; i++)
        a[i] = getStr();

    cout << endl << "------------" << endl << endl;
    printMenu();
    cout << endl;

    ch = getch();

    while (ch != '4') {
        switch (ch) {
            case '1':
                cout << endl << "Enter string to add." << endl;
                str = getStr();
                resize(a, size, size + 1);
                a[size - 1] = str;
                break;
            case '2':
                cout << endl << "Enter string to delete." << endl;
                str = getStr();
                delEntry(a, size, str);
                break;
            case '3':
                cout << endl;
                for (int i = 0; i < size; i++)
                    cout << a[i] << endl;
            case '4':
                break;
            default:
                cout << endl << "Invalid choice.";
        }
        cout << endl << "-------------------" << endl;
        printMenu();
        ch = getch();
    }
}

charPtr getStr() {
    charPtr str;
    str = new char[80];
    cout << ": ";
    cin >> str;
    return str;
}

void printMenu() {
    cout << "[1] Add entry." << endl << "[2] Delete entry." << endl <<
            "[3] List array." << endl << "[4] Exit." << endl << "Choice: ";
}

char getch() {
    char ch;
    cin.ignore(numeric_limits<streamsize>::max(), '\n'); //Flush
    ch = cin.get();
    return ch;
}

strPtr delEntry(strPtr a, int &size, charPtr str) {
    int index = -1;
    resize(a, size, size - 1);
    if (index == -1) return a;
    delStr(a, index, size);
    return a;
}

void resize(strPtr &a, int &size, int new_size) {
    strPtr b;
    b = new charPtr[new_size];

    for (int i = 0; i < new_size; i++)
        b[i] = new char[80];
    for (int i = 0; i < size; i++)
        strcpy(b[i], a[i]);
    delete [] a;
    a = b;
    size = new_size;
}

void delStr(strPtr a, int pos, int size) {
    for (int i = pos; i < size; i++)
        a[i] = a[i + 1];
}

int search(strPtr a, int size, charPtr str) {
    for (int i = 0; i < size; i++)
        if (strcmp(a[i], str) == 0) return i;
}

Recommended Answers

All 3 Replies

>> memory leak?

That's what you have to figure out. "Crash" is too vague. Bad memory management generally fall into a few categories...

  1. You run out of memory. That means you keep allocating and never delete memory and eventually can't allocate.
  2. Deleting memory where you shouldn't, then trying to access it, often cause by two pointers accidentally pointing to the same thing, then deleting the memory pointed to by one of them and try to access it using the other pointer.
  3. Bad pointer. Memory is fine, but somehow you messed up when trying to calculate an address.
  4. NULL pointer. A pointer points to NULL and you try to access the memory.

Which one is your problem? I don't know, but to find out, you should...

  1. Pay extremely close attention to when EXACTLY it occurs as far as line numbers, how far into the program, under what circumstances, etc.
  2. Pay close attention to the rror messages. It'll often tell you, though "segmentation fault" can be a bit vague.
  3. Stick some "assert" statements in there to check for NULL pointers.
  4. Throw some try-catch statements in there for every "new" statement.

You can also look at the Windows Task Manager or the Linux equivalent and see if your memory usage goes up and up and up. Sure-fire indication of a memory leak.

This is when you learn how to use a debugger...

This is a prime example of why I hate typdef of plain-old-data-types. It's very difficult to keep track of what's a char* and what's a char**.

variable a is declared on line 9 as char**, and memory allocated for each rows on line 27. So far, so good. No problem with that. Huge problem on line 31 where the memory allocated on line 27 is destroyed and replaced by a char* returned by call to getStr(). Now there is a big memory leak.

line 101 is another memory leak. It delets a without deleting each of its rows. The resize() function has already copied all the strings in a to array b, so there is no reason to keep all the rows of array a

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.