LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   c++ dynamic array (https://www.linuxquestions.org/questions/programming-9/c-dynamic-array-712863/)

Fredstar 03-19-2009 11:32 AM

c++ dynamic array
 
Hi All,

I'm trying to create a dynamic array in c++. Basically the size of the array is based on the number of lines in an input file.


The code looks like this.

Code:


int main()
{
 int lines = countFileLines();
 int input[lines][3];
}

int countFileLines()
{
 ifstream in_file;
 in_file.open("infile");
 
 if ( !in_file.fail() )
 {
  //count with loop
  //print count which confirms there are 15 lines counted
  return count;
 } else {
  std::cout << "error while trying to open the input file";
  return -1;
 }

}

However, even though my output shows that countFileLines returns 15 i'm getting an error.

Code:

cannot allocate an array of constant size 0
Any idea what im doing wrong?

Thanks in advance

Kunsheng 03-19-2009 11:42 AM

The way you are allocating memory is not dynamic, the compiler has to know the value of 'lines' before execution.

Check this out:
http://www.codeproject.com/KB/cpp/arrayDinamic.aspx

Hope it helps.

+Kunsheng

ErV 03-19-2009 11:58 AM

Quote:

Originally Posted by Fredstar (Post 3480902)
Code:


int main()
{
 int lines = countFileLines();
 int input[lines][3];
}

Any idea what im doing wrong?

Thanks in advance

You can't do that this way in C++. Array size should be known before compilation.
You can use STL std::vector class, or allocate array using new[] or use malloc.
I suggest std::vector or new[].

Fredstar 03-19-2009 12:49 PM

Quote:

Originally Posted by Kunsheng (Post 3480912)
The way you are allocating memory is not dynamic, the compiler has to know the value of 'lines' before execution.

Check this out:
http://www.codeproject.com/KB/cpp/arrayDinamic.aspx

Hope it helps.

+Kunsheng

Thanks for that link its what I wa looking for.

Question, does

Code:

Int **array
Read a pointer of type int points to a pointer of type int? Sorry I'm new to cplusplus and just trying to understand.

Thanks

johnsfine 03-19-2009 01:19 PM

Quote:

Originally Posted by Fredstar (Post 3480902)
The code looks like this.

You left out important parts. Often that is OK, but in this case, I tried replacing the important parts you left out with minimal code and the results worked.
Quote:

Code:

cannot allocate an array of constant size 0

Was that a run time error or compile time error or what?

Quote:

Originally Posted by Kunsheng (Post 3480912)
The way you are allocating memory is not dynamic

Actually it is dynamic but ...

Quote:

Originally Posted by ErV (Post 3480933)
You can't do that this way in C++.

I believe it is not allowed by the C++ standard. But g++ accepts it and makes it work correctly.

Quote:

Originally Posted by Fredstar (Post 3481002)
Thanks for that link its what I wa looking for.

I think it isn't what you were looking for. I think it has a lot of extra complexity, apparently to allow the minor dimension to be dynamic. But you seem to need only the major dimension to be dynamic, which ought to be simpler, maybe even as simple as what you originally quoted (that is not valid C++, but can work).

Quote:

does
Code:

Int **array
Read a pointer of type int points to a pointer of type int?
C declarations can be counter intuitive.

In this case, reading from the "inside" outward, you see:
array is a pointer.
the thing it points to is a pointer.
the thing that points to is an int.

ErV 03-19-2009 01:24 PM

Quote:

Originally Posted by johnsfine (Post 3481029)
I believe it is not allowed by the C++ standard. But g++ accepts it and makes it work correctly.

g++ probably accepts it only if value of variable used for array size can be calculated during compile time. If it allows things like this:
Code:

int size = rand() & 0xFF;
int test[size];

and they behave correctly, then I'll be very surprised.

Quote:

Originally Posted by Fredstar (Post 3481002)
Question, does

Code:

Int **array
Read a pointer of type int points to a pointer of type int?

It reads as "pointer to a pointer to an int".

johnsfine 03-19-2009 01:34 PM

Quote:

Originally Posted by ErV (Post 3481037)
g++ probably accepts it only if value of variable used for array size can be calculated during compile time. If it allows things like this:
Code:

int size = rand() & 0xFF;
int test[size];

and they behave correctly, then I'll be very surprised.

Here is what I tested. It works for me. How much more do you need before you're surprised?

Code:

#include <iostream>
int countFileLines();

int main()
{
 int lines = countFileLines();
 int input[lines][3];
 std::cout << "uninitialized value at input[" << lines-1 <<"][2] = " << input[lines-1][2] << std::endl;
 return 0;
}

int countFileLines()
{
  std::cout << "How big should it be?";
  int result;
  std::cin >> result;
  return result;
}


Biddle 03-19-2009 02:43 PM

Yes this is a g++ extension adding pedantic to the compile flags will cause it to fail.

ta0kira 03-19-2009 03:00 PM

Quote:

Originally Posted by johnsfine (Post 3481052)
Here is what I tested. It works for me. How much more do you need before you're surprised?

That's definitely invalid C++. Also, you can read int all day from any address in the current memory space without problems. Just to make sure, though, I modified it a little and sure enough it allocates stack space for the array.
Code:

#include <iostream>
#include <stdio.h>

int countFileLines();

struct testme
{
    ~testme()
    { fprintf(stderr, "destruct\n"); }
};

int main()
{
 int lines = countFileLines();
 fprintf(stderr, "%p ", &lines);
 testme input[lines][3];
 int test;
 fprintf(stderr, "%p %p => %i\n", &input, &test, (int) &test - (int) &input);
 return 0;
}

int countFileLines()
{
  std::cout << "How big should it be?";
  int result;
  std::cin >> result;
  return result;
}

You'll see the difference output correlates with the size you specify. However, this still isn't valid C++, even though g++ will compile it with the -ansi flag. If you don't believe me, run either test by Comeau or post it to comp.lang.c++.moderated and see how many people laugh.
Kevin Barry

ta0kira 03-19-2009 03:01 PM

Quote:

Originally Posted by johnsfine (Post 3481029)
Actually it is dynamic but ...

Maybe it's better to just say "stack" and "heap" because it's all technically dynamic.
Kevin Barry

johnsfine 03-19-2009 03:34 PM

Quote:

this still isn't valid C++, even though g++ will compile it with the -ansi flag. If you don't believe me, run either test by Comeau or post it to comp.lang.c++.moderated and see how many people laugh.

I don't think anyone here suggested it was valid C++. I said I thought is was NOT valid C++. (privately I was sure it was not valid C++, but I prefer not to express certainty about the C++ standard unless I'm actually looking at the relevant section of the standard when I make the statement.)


I think the original question was why it didn't work for the OP (we still don't know) and the further question was whether it works in g++ (it does).

Quote:

Originally Posted by ta0kira (Post 3481164)
you can read int all day from any address in the current memory space without problems. Just to make sure, though, I modified it a little and sure enough it allocates stack space for the array.

I put in some moderately large numbers at run time and verified that way that it does allocate stack space.

sundialsvcs 03-19-2009 04:06 PM

Usually, the way that I like to handle such requirements is with some convenient kind of "container class." In other words, a hash or a list or something that I can easily refer-to using "(say...) a number" as an index.

Although it is "natural" to envision such a thing as being "a 'square' block of storage whose elements can be accessed by multiplication from a base-address," such a perspective is quite limited ... especially if the array is known to be sparse.

Perhaps counter-intuitively, such an arrangement can actually be more efficient than the alternative, especially if the array is large, because "memory" is virtual. Data-structures that have a large "footprint" are therefore penalized... sometimes, quite considerably.

ErV 03-19-2009 04:28 PM

Quote:

Originally Posted by johnsfine (Post 3481052)
Here is what I tested. It works for me.

Well, it is bad, because it shouldn't do this. I'd go as far as to call this a flaw.

Biddle 03-19-2009 04:37 PM

Quote:

Well, it is bad, because it shouldn't do this.
g++ or any implementation is allowed to do a lot of things using extensions, but if it _should_ do it or not is only yours/my opinion.

Quote:

Originally Posted by ErV (Post 3481250)
I'd go as far as to call this a flaw.

So would I but the standard and g++ call it an extension :)

johnsfine 03-19-2009 05:27 PM

Quote:

Originally Posted by ErV (Post 3481250)
Well, it is bad, because it shouldn't do this. I'd go as far as to call this a flaw.

In my opinion, the lack of this feature in the standard is a flaw in the standard.

That isn't necessarily a contradiction to your claim that support for this non standard feature is a flaw in g++. But, on balance, I disagree with that at well. Why should the language make things harder for the programmer when it is easy to make things easier for the programmer?

This extension is certainly not a confusing syntax. It is not an error prone feature to use (anyway less so than using new or std::vector or any of the other ways of getting the same functionality).

Its biggest flaw is that it hides a potential cost/limit (the risk of stack overflow). But C++ generally hides costs and limits (that is one of the flaws of the language). Like C, C++ gives you the level of control needed to write very tight code. But unlike C, C++ tends to also let you write concise, fairly simple looking code that costs much more (time/space) to run than you might guess by looking at it.

This form of allocation for a run time determined amount of data is usually more efficient than using new or std::vector or any other method approved by the C++ standard. It is simpler to code and easier to understand when reading the code.

Unfortunately, both Windows and Linux lay out the x86 32 bit address space in a stupid manner creating an unnecessary constraint on stack size, which makes this g++ extension a little less useful on those (and other common) architectures. But it is still usually useful and a C++ programmer is supposed to know when a feature shouldn't be used because of costs or limits.


All times are GMT -5. The time now is 03:37 PM.