0

I'm pretty new to C++ and I have some problems with getting into all that pointer stuff. Basically I am passing a pointer to a Function, creating an Array at that pointer. Back in the main function I can't access this array.

Here's my code:

#include <iostream>

using namespace std;

void createArray(char** dict, int* arraysize)
{
    *arraysize = 26*26*26*26;

    delete dict;
    dict = 0;

    //Initialisiere character array of character
    //char **wortliste = 0;
    dict = new char*[*arraysize];
    for(int i = 0; i < *arraysize; i++)
        dict[i] = new char[5];

    int ctr = 0;

    //Erstelle Einträge (sortiert)
    for (char i = 'A'; i <= 'Z'; i++)
    {
        for (char j = 'A'; j <= 'Z'; j++)
        {
            for (char k = 'A'; k <= 'Z'; k++)
            {
                for (char l = 'A'; l <= 'Z'; l++)
                {
                    dict[ctr][0] = i;
                    dict[ctr][1] = j;
                    dict[ctr][2] = k;
                    dict[ctr][3] = l;
                    dict[ctr][4] = '\0';
                    ctr++;
                }
            }
        }
    }
}

int main(void)
{
    char** dict = 0;
    int arraysize;

    createArray(dict, &arraysize);

    cout << dict[0] << endl << dict[arraysize-1] << endl;

    return 0;
}

I can't figure out my error thank you very much in advance.

metacircle
  • 2,438
  • 4
  • 25
  • 39

3 Answers3

2

In C++ parameters are pass by value (unless explicitly marked as being reference parameters), so when you pass dict, a pointer (to a pointer to char) to createArray, the dict inside your function is a different object, albeit with the same initial value, as the dict in main. If you want to see changes to dict in main you would have to pass it by reference, or pass the address of it into a function taking a char ***.

E.g.

void createArray(char**& dict, int* arraysize)

or

void createArray(char*** pdict, int* arraysize)
{ // use (*pdict) instead of dict ...

and

// ...
createArray(&dict, &arraysize);

A more "C++" way to achieve what you want would be to have:

void createArray( std::vector<std::string>& dict );

and to simply have createArray resize the vector to the required size. Using standard containers like vector and string also frees you of the obligation to explicity deallocate that memory that you allocate which is currently missing from your code.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • Exactly. The `dict` argument should be treated the same as the `arraysize` argument. In both cases, you are wanting to return a value from `createArray()` in each variable. That requires the **address** of *both* variables to be passed in. – Matt Davis Dec 16 '11 at 08:06
  • 1
    I can't believe people are trying to help him do things the way he wants to do them. – Karl Knechtel Dec 16 '11 at 08:13
  • @KarlKnechtel: We all have to start from somewhere. Yes, it's good to learn about better ways to achieve the same thing but it is also valuable to be able to learn what is wrong with code that we are trying to work with and trying to fix. Even if you do use `vector` and `string` you still have to understand about how the language works and pass-by-value otherwise you will only end up making the same comprehension errors, only with different objects. – CB Bailey Dec 16 '11 at 08:17
  • @CharlesBailey well, sure, but that way you can at least study those issues in isolation instead of getting tangled up with the vagaries of raw memory management at the same time. – Karl Knechtel Dec 16 '11 at 08:18
  • @KarlKnechtel: Given the context of the question I stand by my answer. – CB Bailey Dec 16 '11 at 08:22
1

There are a couple of mistakes.

  1. To delete an array:

    char **array = /* new with whatever */;
    /* do your work */
    for (i = 0; i < array_size; ++i)
        delete[] array[i];
    delete[] array;
    
  2. To new an array:

    char **array = new char *[array_size];
    for (i = 0; i < array_size; ++i)
        array[i] = new char[array_size_2];
    
  3. When deleteing, to make sure you don't iterate over a not-newed array, check it against NULL:

    for (i = 0; i < array_size; ++i)
    {
        if (array[i] != NULL)   /* Or simply if (array[i]) */
            delete[] array[i];
        array[i] = NULL;
    }
    if (array != NULL)
        delete[] array;
    array = NULL;
    

    alternatively, since delete makes a check for NULL anyway, you can simplify this to:

    if (array != NULL)
        for (i = 0; i < array_size; ++i)
            delete[] array[i];  /* no need to set to NULL after if going to delete the array */
    delete[] array;
    array = NULL;
    

Note: delete deletes a single object while delete[] deletes an array.

Shahbaz
  • 46,337
  • 19
  • 116
  • 182
0

I can't imagine what you would do with such data, but you can at least use modern techniques.

#include <iostream>
#include <vector>
#include <string>

using namespace std;

vector<string> create() {
    vector<string> result;
    for (char i = 'A'; i <= 'Z'; ++i) {
        for (char j = 'A'; j <= 'Z'; ++j) {
            for (char k = 'A'; k <= 'Z'; ++k) {
                for (char l = 'A'; l <= 'Z'; ++l) {
                    result.push_back(string() + i + j + k + l);
                }
            }
        }
    }
    return result;
}

int main() {
    vector<string> data = create();
    cout << data.front() << endl << data.back() << endl;
}
Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
  • Well I have to do this for some assignment. I come from the C# world, unfortunately I don't have time at the moment to become familiar with modern C++ techniques since all the literature I have uses the "classic" C++ approach. Also your code gives me a LINKER error on MSVC 10. – metacircle Dec 16 '11 at 08:21
  • If you already know how to program in C#, taking an actual class to learn C++ is not going to be very useful to you. As for your error, I cannot debug it without details. – Karl Knechtel Dec 16 '11 at 08:24
  • It seems to have something to do with the DEBUG Profile, the Release Profile works. See also here: http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/5e126c79-77f3-4d50-a47f-a9ce35cff0a4 – metacircle Dec 16 '11 at 08:28
  • Can you recommend literature containing modern C++ techniques then? – metacircle Dec 16 '11 at 08:55
  • You should start here: http://www.parashift.com/c++-faq-lite/ , and then if you are not in an environment where you can get access to well-written modern code (you almost certainly aren't), you may try reading anything by Alexandrescu, Koenig, or Sutter (these names are very Google-able in a C++ context). Do **not** read anything by Schildt; it is very well known for making wrong statements confidently. – Karl Knechtel Dec 16 '11 at 09:01