Question

[EDIT]

Okay, so that makes sense, thank you sharptooth and CashCow. You can't delete data allocated as const, which makes string literals out of the question. So if I change my initialization to look like this:

char **groups = new char*[2];

char *s1 = new char[10];
char *s2 = new char[10];
char c1 = 'a';
char c2 = 'b';
for(int i = 0; i < 9; i++)
{
    s1[i] = c1;
    s2[i] = c2;
}
s1[9] = NULL;
s2[9] = NULL;

groups[0] = s1;
groups[1] = s2;

Hard code my for loop so that it will only iterate through i=1 and i=2, then everything works.

I noticed that the int arraySize = sizeof arr / sizeof *arr; only seems to work when the array is allocated with new[] instead of locally. This is because my original char ** groups; variable decays to a pointer, right?

Now I'm wondering, is there anyway to tell whether or not data is const?


[ORIGINAL]

I know that arrays and pointers are evil, and that there are these great things called vectors and linked lists.

But, I'm a newbie when it comes to memory management, and I'm feeling a little masochistic. Say I make an array of C-strings. I know from this question and the FAQ-Lite that you must match type a = new type[len]; with delete[] a;. Or so I think.

FAQ-Lite talks about managing jagged arrays here, but he's focusing on matrices, and I'm not certain if it applies to what I'm doing.

This code makes sense to me, but fails an assertion (debugging on Visual Studio 2008) on delete[] a;. What is wrong with this, and how do I accomplish this task?

#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{
    // Initialize array of C-strings
    char *groups[] = {"testing1", "testing2"};

    // Sanity check
    cout << groups[0] << endl;
    cout << groups[1] << endl;

    // Compute size
    int arrsize = sizeof groups / sizeof groups[0];
    cout << arrsize << endl;

    for (int i = 0; i < arrsize; i++)
    {
        // Since each string is a char array, free string memory with delete[]
        cout << "Deleting element #" << i << endl;
        delete[] groups[i];
    }
    cout << "Freeing pointer array." << endl;

    // Free the memory storing the pointers
    delete[] groups;

    return 0;
}
Was it helpful?

Solution

You try to deallocate string literals - that's undefined behavior:

char *groups[] = {"testing1", "testing2"};
delete[] groups[i];

only call delete[] on pointers returned by new[].

OTHER TIPS

Literal strings are expressions like "testing1". They are of type const char *. They cannot be modified and they cannot be deleted. The actual text usually sits in the static read-only memory area of the program.

You can construct a char array that is writable like this:

char group[] = "testing1";

That is modifiable but you cannot delete it, nor can you extend it to make it bigger. It also has local scope so you cannot return it from a function.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top