LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-19-2009, 11:32 AM   #1
Fredstar
Member
 
Registered: Jul 2004
Location: Rochester, NY
Distribution: Fedora9::FreeBSD7.1
Posts: 296

Rep: Reputation: 30
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
 
Old 03-19-2009, 11:42 AM   #2
Kunsheng
Member
 
Registered: Mar 2009
Posts: 82

Rep: Reputation: 16
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
 
Old 03-19-2009, 11:58 AM   #3
ErV
Senior Member
 
Registered: Mar 2007
Location: Russia
Distribution: Slackware 12.2
Posts: 1,202
Blog Entries: 3

Rep: Reputation: 62
Quote:
Originally Posted by Fredstar View Post
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[].
 
Old 03-19-2009, 12:49 PM   #4
Fredstar
Member
 
Registered: Jul 2004
Location: Rochester, NY
Distribution: Fedora9::FreeBSD7.1
Posts: 296

Original Poster
Rep: Reputation: 30
Quote:
Originally Posted by Kunsheng View Post
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
 
Old 03-19-2009, 01:19 PM   #5
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by Fredstar View Post
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 View Post
The way you are allocating memory is not dynamic
Actually it is dynamic but ...

Quote:
Originally Posted by ErV View Post
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 View Post
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.

Last edited by johnsfine; 03-19-2009 at 01:26 PM.
 
Old 03-19-2009, 01:24 PM   #6
ErV
Senior Member
 
Registered: Mar 2007
Location: Russia
Distribution: Slackware 12.2
Posts: 1,202
Blog Entries: 3

Rep: Reputation: 62
Quote:
Originally Posted by johnsfine View Post
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 View Post
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".
 
Old 03-19-2009, 01:34 PM   #7
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by ErV View Post
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;
}
 
Old 03-19-2009, 02:43 PM   #8
Biddle
Member
 
Registered: Jan 2009
Posts: 37

Rep: Reputation: 17
Yes this is a g++ extension adding pedantic to the compile flags will cause it to fail.
 
Old 03-19-2009, 03:00 PM   #9
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by johnsfine View Post
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
 
Old 03-19-2009, 03:01 PM   #10
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by johnsfine View Post
Actually it is dynamic but ...
Maybe it's better to just say "stack" and "heap" because it's all technically dynamic.
Kevin Barry
 
Old 03-19-2009, 03:34 PM   #11
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
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 View Post
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.

Last edited by johnsfine; 03-19-2009 at 03:36 PM.
 
Old 03-19-2009, 04:06 PM   #12
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,649
Blog Entries: 4

Rep: Reputation: 3934Reputation: 3934Reputation: 3934Reputation: 3934Reputation: 3934Reputation: 3934Reputation: 3934Reputation: 3934Reputation: 3934Reputation: 3934Reputation: 3934
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.
 
Old 03-19-2009, 04:28 PM   #13
ErV
Senior Member
 
Registered: Mar 2007
Location: Russia
Distribution: Slackware 12.2
Posts: 1,202
Blog Entries: 3

Rep: Reputation: 62
Quote:
Originally Posted by johnsfine View Post
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.
 
Old 03-19-2009, 04:37 PM   #14
Biddle
Member
 
Registered: Jan 2009
Posts: 37

Rep: Reputation: 17
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 View Post
I'd go as far as to call this a flaw.
So would I but the standard and g++ call it an extension

Last edited by Biddle; 03-19-2009 at 04:40 PM.
 
Old 03-19-2009, 05:27 PM   #15
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by ErV View Post
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.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Dynamic Array Sizes JMJ_coder Programming 8 03-05-2008 07:33 PM
list with dynamic array TurtleFace Programming 7 11-05-2006 06:58 PM
expanding dynamic array niteshadw Programming 6 06-25-2005 11:19 PM
More dynamic array problems PTBmilo Programming 5 03-14-2003 12:51 AM
dynamic array in class help PTBmilo Programming 6 03-09-2003 02:35 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 09:52 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration