Pointer, heap memory, neither?

My array goes "out of scope" in the following code snippet, any ideas on how I should get around this? I'm not good with pointers or with declaring variables using heap memory yet but I know enough to think these might be the answer to my problem.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
int reservearray (int array3[], int maxnumberofelements)
{
    int numberofinputs;

    for (numberofinputs = 0; numberofinputs < maxnumberofelements; numberofinputs++)
    {
        cout<<"Please input a seat ID number to be reserved: ";

        int inputvalue;
        cin>>inputvalue;

        if (inputvalue < 0)
        {
            break;
        }
        array3[numberofinputs] = inputvalue;
        int dispreservedarray[numberofinputs];

        for (int x = 0; x < maxnumberofelements; x++)
        {
            dispreservedarray[x] = x;

            if (array3[numberofinputs] == dispreservedarray[x])
            {
                dispreservedarray[x] = 'x';
            }
        }
    }
    cout<<dispreservedarray[x];
}


I'm trying to display dispreservedarray[x] as the last part of the function, but, like I said, It goes out of scope...
Last edited on
For the curious, the rest of this question is here:
http://www.cplusplus.com/forum/beginner/48643/

Firstly, the logic here doesn't make any sense. Why do you ask the user maxnumberofelements times to input a seat ID? Shouldn't you keep asking them until they want to quit? (I noticed now that the user is asked up to maxnumberofelements times, though getting the user input and doing the next update operation every iteration doesn't make sense.)

Next, you save the current request in array3. You shouldn't have to do this unless you need to store the user's requests in order.

And an operation like this shouldn't be done in the main loop:

1
2
3
4
5
6
7
8
9
10
11
int dispreservedarray[numberofinputs];

for (int x = 0; x < maxnumberofelements; x++)
{
     dispreservedarray[x] = x;

     if (array3[numberofinputs] == dispreservedarray[x])
     {
          dispreservedarray[x] = 'x';
     }
}


Speaking of this operation, this int dispreservedarray[numberofinputs]; causes undefined behaviour as you can't create an array with a length not known at compile time (without new or malloc). Also, the loop goes to maxnumberofelements yet the array dispreservedarray is numberofinputs long. And lastly, in the first iteration this array will be zero length (!), then the next it will be of length 1, then 2, etc.

cout<<dispreservedarray[x];

Not only is dispreservedarray out of scope here, but so is x. If you want to display the whole array, you will have to do it in a loop. As I said, you will have to re-examine the logic here.

Pointer, heap memory, neither?

If you're willing to overwrite array3 then the answer is neither. As seat IDs come in from the user, you could do array3[inputvalue] = 'x';. No need to remember the requests.

If the plan needs to be placed in dispreservedarray then you'll have to create it on the heap and copy array3 over to it (although in the code you posted before, array3 was uninitialized).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int* dispreservedarray = new int[maxnumberofelements];

//copy array3 into dispreservedarray (if applicable)
for(int i = 0; i < maxnumberofelements; i++)
{
     dispreservedarray[i] = array3[i];
}

//ask for requests from the user, and as they come in, assign them
//to dispreservedarray

//display the array

//finished
delete [] dispreservedarray;
Last edited on
Thanks for clearing up my logic there. I've written something similar now and it works almost perfectly. It's just that it doesn't replace the number I've already assigned to array3 with an 'x'. I didn't expect that to work anyway, but how would I get around this? I want to display whole array like [1] [2] [3] [4] etc. except with x's in the places that the user inputs (I hope none of that was confusing). Any suggestions?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
int reservearray (int maxnumberofelements)
{
    int numberofinputs;
    int *array3 = new int[maxnumberofelements];

    for (int i = 0; i < maxnumberofelements; i++)
    {
        array3[i] = i;
    }

    for (numberofinputs = 0; numberofinputs < maxnumberofelements; numberofinputs++)
    {
        cout<<"Please input a seat ID number to be reserved: ";

        int inputvalue;
        cin>>inputvalue;

        if (inputvalue < 0)
        {
            break;
        }

        array3[inputvalue] = 'x';
    }
    cout<<"\n";

    for (int i = 0; i < maxnumberofelements; i++)
    {
        cout<<"["<<array3[i]<<"]";

        if (i == 7) {cout<<"\n";}
        if (i == 15) {cout<<"\n";}
        if (i == 23) {cout<<"\n";}
        if (i == 31) {cout<<"\n";}
        if (i == 3) {cout<<"\t\t";}
        if (i == 11) {cout<<"\t\t";}
        if (i == 19) {cout<<"\t";}
        if (i == 27) {cout<<"\t";}
        if (i == 35) {cout<<"\t";}
    }
    delete []array3;
}
Firstly, this function is declared as returning an int yet it doesn't return anything. Declare it void if it's not meant to return anything.

The problem here is you want array3 to store ints ([0][1][2][3]...) as well as the char 'x'. This is actually possible because ints and chars are convertible types, though the way you do it, it outputs x as its ASCII value (120).

I would suggest a minor change: in the output loop, check if array3[i] is equal to the ASCII value of 'x'. You could store its ASCII value as a constant, i.e. const int ASCII_X = 'x';. Then, if array3[i] is the ASCII of 'x', then display 'x', otherwise print its value as normal.
Aside

This line confuses me:

int dispreservedarray[numberofinputs];

(where numberofinputs is an int loop variable, not a const.)

Shaktar mentions that "you can't create an array with a length not known at compile time".

But as C++ requires a constant expression when declaring an array, I would have thought that the code should not compile.

With VC++ and attempt to declare an array like that results in an error: "expected constant expression". So -- for future reference -- I was wondering what compiler is not blocking this definition.

Andy
Last edited on
Last edited on
@shacktar - thanks for the ref...

I had looked around for info, but that thread makes things somewhat clearer.

I am surprise it's GCC -- I thought that it was a very well behaved compiler.

But as Dev-C++ is involved : I have seen posts on this site warning that Dev-C++ uses a backdated version of GCC (unless you manually update it). So I whould hope that this is only an issue with older versions of the Gnu compiler.
Last edited on
andywestken wrote:
I am surprise it's GCC -- I thought that it was a very well behaved compiler.

Actually, it's microsoft that doesn't conform to the standard. Variable length arrays are a C99 feature.

Wikipedia says:
Most C compilers now have support for at least some of the features new to C99. However,
there has been less support from vendors such as Microsoft that have mainly focused on C++.

http://en.wikipedia.org/wiki/C99#Implementations
Last edited on
@m4ster r0shi

If it's a C feature, why is it being accepted in a .cpp file? (The code above code is using C++ feature, so it can't be a .c file.)

I don't realy want there to be any blurring between the languages. I hope there is a way to disable this and other C99 specific behaviour!

Compile with the -pedantic-errors flag, and it will reject it (forbidden extensions).
man gcc wrote:
A feature to report any failure to conform to ISO C might be useful in some instances, but would require considerable additional work and would be quite different from -pedantic. We don't have plans to support such a feature in the near future.


@OP: try to solve the problem with just 1 array of Booleans.
ne555 wrote:
Compile with the -pedantic-errors flag,
and it will reject it (forbidden extensions).

Indeed.

andywestken wrote:
If it's a C feature, why is it being accepted in a .cpp file?

I went with the "C++ is a superset of C"
rule, but I guess this is not entirely true...

Wikipedia says:
[...] C99 introduced a number of new features that C++
does not support, such as variable-length arrays [...]

http://en.wikipedia.org/wiki/C%2B%2B#With_C
@ne555 / @m4ster r0shi

Thanks for the pointer to the pedantic' flag.

And also at the C99 info. I was kind of aware that it existed, but I hadn't expected its feature to turn up in my vicinity!
I think I have done exactly what you said, shack, yet it still displays the ASCII value instead of 'x'. I think this is because I don't exactly know how to "display" it correctly. I seem to have repeated my problem with
array3[i] = 'x' I may not be familiar with what you were implying me to do because, if you don't already know, I'm kind of a beginner here. Here's the output loop:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
for (int i = 0; i < maxnumberofelements; i++)
    {
        const int ASCII_X = 'x';

        if (array3[i] == ASCII_X)
        {
            array3[i] = 'x';
        }
        cout<<"["<<array3[i]<<"]";

        if (i == 7) {cout<<"\n";}
        if (i == 15) {cout<<"\n";}
        if (i == 23) {cout<<"\n";}
        if (i == 31) {cout<<"\n";}
        if (i == 3) {cout<<"\t\t";}
        if (i == 11) {cout<<"\t\t";}
        if (i == 19) {cout<<"\t";}
        if (i == 27) {cout<<"\t";}
        if (i == 35) {cout<<"\t";}
    }
Last edited on
Not quite. You're setting the array element to 'x' if it's already 'x', then displaying it as before.

shacktar suggested you display a char 'x' if the int value == asc value of 'x'

That is,

1
2
3
4
5
6
7
8
9
10
    for (int i = 0; i < maxnumberofelements; i++)
    {
        const char ASCII_X = 'x'; // needs to be a char to display right

        if (array3[i] == ASCII_X)
            cout<<"["<<ASCII_X<<"]";
        else
            cout<<"["<<array3[i]<<"]";

        ...


(might make sense to handle the brackets outside the if condition?)

Andy

P.S. std::setw might be of interest to you? see stl help.
Last edited on
Oh, i get it now, thank you andy and shack, you have been very helpful! Everything's fine and dandy now. I'm also glad people other than myself got something from this post. Thanks again!
Topic archived. No new replies allowed.