1,105,625 Community Members

Variable size for second subscript of an Array

Member Avatar
PrimePackster
Posting Whiz in Training
252 posts since Nov 2011
Reputation Points: 10 [?]
Q&As Helped to Solve: 17 [?]
Skill Endorsements: 3 [?]
 
0
 

Well
I just want to know, how to give variable size for an array(Particularly, second subscript).

For example, like this

#include<iostream>

using namespace std;
int main()
{
	int a,b;
	cout<<"Enter the size for the 2D array"<<endl;
	cin>>a>>b;
	int*A=new int[a][b];

for a its ok, But how to make it work for b too..

Member Avatar
PrimePackster
Posting Whiz in Training
252 posts since Nov 2011
Reputation Points: 10 [?]
Q&As Helped to Solve: 17 [?]
Skill Endorsements: 3 [?]
 
0
 

Here is the full pgm i have been trying to test the dynamic array initialization..

// Simple2Darray.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"


int _tmain(int argc, _TCHAR* argv[])
{
	return 0;
}

#include<iostream>

using namespace std;
int main()
{
	int a,b;
	cout<<"Enter the size for the 2D array"<<endl;
	cin>>a>>b;
	int*A=new int[a][b];
	for(int i=0;i<a;i++)
	{
		for(int j=0;j<b;j++)
		{
			cin>>A[i][j];
		}
	}
	for(i=0;i<a;i++)
	{	cout<<endl;
		for(int j=0;j<b;j++)
		{
			cout<<A[i][j]<<" ";
		}
	}
	system("PAUSE");
	return 0;
}
Member Avatar
mikrosfoititis
Junior Poster in Training
74 posts since Nov 2011
Reputation Points: 0 [?]
Q&As Helped to Solve: 12 [?]
Skill Endorsements: 1 [?]
 
0
 

what about just int A[a][b] ?

Member Avatar
Fbody
Posting Maven
2,845 posts since Oct 2009
Reputation Points: 682 [?]
Q&As Helped to Solve: 393 [?]
Skill Endorsements: 7 [?]
Featured
 
0
 

what about just int A[a][b] ?

Unfortunately, that's not technically allowed by many compilers because a and b are not constants. Since they are not constants, they are not known and the array can't be allocated at compile time. I hear it's technically legal under newer versions of the standards, but not every compiler supports the newer standards yet.

@OP:
I think what you have will work on a compiler that follows the new standard, but I'm not sure. I do know though that your array needs to be declared as a pointer to pointer ("double pointer"), not a ("single") pointer.

To have a truly reliable (portable) implementation though, it's better to explicitly use dynamic allocation. To do so, you declare a "double pointer" to a dataType. Then you allocate to that "double pointer" a 1-dimensional array of "single" pointers to the same dataType. Then you allocate to each "single" pointer within the array a 1-dimensional array of that dataType (actual objects/instances, not pointers). Something like this:

int **myDynamicArray = new int *[a];
for (int i = 0; i < a; ++i) {
  myDynamicArray[i] = new int[b];
}
Member Avatar
Narue
Bad Cop
12,139 posts since Sep 2004
Reputation Points: 5,693 [?]
Q&As Helped to Solve: 1,537 [?]
Skill Endorsements: 81 [?]
Team Colleague
 
0
 

I hear it's technically legal under newer standards, but not every compiler supports the newer standards yet.

Not in C++. The current C standard (C99) supports variable length arrays, but they're an abomination and shouldn't be used. C++ doesn't support variable length arrays in any form because the standard library handles all but the most niche of VLA use cases.

To have a truly reliable (portable) implementation, it's better to explicitly use dynamic allocation.

Or implicitly use dynamic allocation with std::vector. You're doing the same thing with fewer features and a greater chance of implementation bugs.

Member Avatar
Fbody
Posting Maven
2,845 posts since Oct 2009
Reputation Points: 682 [?]
Q&As Helped to Solve: 393 [?]
Skill Endorsements: 7 [?]
Featured
 
0
 

Not in C++. The current C standard (C99) supports variable length arrays, but they're an abomination and shouldn't be used. C++ doesn't support variable length arrays in any form because the standard library handles all but the most niche of VLA use cases.


Or implicitly use dynamic allocation with std::vector. You're doing the same thing with fewer features and a greater chance of implementation bugs.

I kind-of get the impression this is a dynamic-allocation-related assignment, but I bow to your wisdom: :P :)

Member Avatar
Narue
Bad Cop
12,139 posts since Sep 2004
Reputation Points: 5,693 [?]
Q&As Helped to Solve: 1,537 [?]
Skill Endorsements: 81 [?]
Team Colleague
 
0
 

I kind-of get the impression this is a dynamic-allocation-related assignment

It's not obviously homework, but even if it were, we would be doing the student a disservice by not mentioning the better alternative for future projects.

Member Avatar
PrimePackster
Posting Whiz in Training
252 posts since Nov 2011
Reputation Points: 10 [?]
Q&As Helped to Solve: 17 [?]
Skill Endorsements: 3 [?]
 
0
 

Or implicitly use dynamic allocation with std::vector. You're doing the same thing with fewer features and a greater chance of implementation bugs.

So can you please explain how to use this std::vector?

It's not obviously homework, but even if it were, we would be doing the student a disservice by not mentioning the better alternative for future projects.

Well off-course not, this is not a homework. Well for some reason, i have been asked to use constant size for arrays, but i believe there is always a way around. So i am on to it. Just learned how to make it work for 1D array. Not for 2D, second subscript is the problem.

I think what you have will work on a compiler that follows the new standard, but I'm not sure. I do know though that your array needs to be declared as a pointer to pointer ("double pointer"), not a ("single") pointer.

Well i am using VC++ 2010 Express Edition...

Member Avatar
Fbody
Posting Maven
2,845 posts since Oct 2009
Reputation Points: 682 [?]
Q&As Helped to Solve: 393 [?]
Skill Endorsements: 7 [?]
Featured
 
0
 

So can you please explain how to use this std::vector?

Well off-course not, this is not a homework. Well for some reason, i have been asked to use constant size for arrays, but i believe there is always a way around. So i am on to it. Just learned how to make it work for 1D array. Not for 2D, second subscript is the problem.

Well i am using VC++ 2010 Express Edition...

That still follows an older standard. The code that I posted earlier was written on VC++ 2008.

Here is some info on the Standard Template Library (the "STL"). The std::vector, as well as several other container templates, is part of the STL.

Member Avatar
Narue
Bad Cop
12,139 posts since Sep 2004
Reputation Points: 5,693 [?]
Q&As Helped to Solve: 1,537 [?]
Skill Endorsements: 81 [?]
Team Colleague
 
1
 

So can you please explain how to use this std::vector?

Certainly. Here's a rough facsimile of your code using std::vector:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    int a, b;
    
    cout << "Enter the size for the 2D array: ";
    
    if (cin >> a >> b) {
        vector<vector<int>> vec(a, vector<int>(b));
        int k = 0;
        
        for (int i = 0; i < a; i++) {
            for (int j = 0; j < b; j++)
                vec[i][j] = k++;
        }
        
        for (int i = 0; i < a; i++) {
            for (int j = 0; j < b; j++)
                cout << vec[i][j] << ' ';
                
            cout << '\n';
        }
    }
}

The only real difference is in the constructor where you need to build up both dimensions. This is the proper way to do it if you already know the sizes, but you can grow the vector dynamically as you go if necessary, that's where the real power lies:

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

using namespace std;

int main()
{
    vector<vector<int>> vec;
    string line;
    
    cout << "Enter a table (EOF to finish):\n";
    
    while (getline(cin, line)) {
        // Insert a new row to the vector
        vec.push_back(vector<int>());
        
        istringstream iss(line);
        int x;
        
        while (iss >> x)
            vec.back().push_back(x);
    }
    
    for (int i = 0; i < vec.size(); i++) {
        for (int j = 0; j < vec[i].size(); j++)
            cout << vec[i][j] << ' ';
            
        cout << '\n';
    }
}
Member Avatar
frogboy77
Posting Pro in Training
477 posts since Aug 2010
Reputation Points: 73 [?]
Q&As Helped to Solve: 43 [?]
Skill Endorsements: 1 [?]
 
0
 
vector<vector<int>> vec(a, vector<int>(b));

Is this compilable? (i.e without the white space)

Member Avatar
Narue
Bad Cop
12,139 posts since Sep 2004
Reputation Points: 5,693 [?]
Q&As Helped to Solve: 1,537 [?]
Skill Endorsements: 81 [?]
Team Colleague
 
1
 

Is this compilable? (i.e without the white space)

Yes, that particular annoyance was removed in C++11. The OP's compiler (Visual C++ 2010) supports the new feature.

Member Avatar
PrimePackster
Posting Whiz in Training
252 posts since Nov 2011
Reputation Points: 10 [?]
Q&As Helped to Solve: 17 [?]
Skill Endorsements: 3 [?]
 
0
 

Certainly. Here's a rough facsimile of your code using std::vector:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    int a, b;
    
    cout << "Enter the size for the 2D array: ";
    
    if (cin >> a >> b) {
        vector<vector<int>> vec(a, vector<int>(b));
        int k = 0;
        
        for (int i = 0; i < a; i++) {
            for (int j = 0; j < b; j++)
                vec[i][j] = k++;
        }
        
        for (int i = 0; i < a; i++) {
            for (int j = 0; j < b; j++)
                cout << vec[i][j] << ' ';
                
            cout << '\n';
        }
    }
}

The only real difference is in the constructor where you need to build up both dimensions. This is the proper way to do it if you already know the sizes, but you can grow the vector dynamically as you go if necessary, that's where the real power lies:

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

using namespace std;

int main()
{
    vector<vector<int>> vec;
    string line;
    
    cout << "Enter a table (EOF to finish):\n";
    
    while (getline(cin, line)) {
        // Insert a new row to the vector
        vec.push_back(vector<int>());
        
        istringstream iss(line);
        int x;
        
        while (iss >> x)
            vec.back().push_back(x);
    }
    
    for (int i = 0; i < vec.size(); i++) {
        for (int j = 0; j < vec[i].size(); j++)
            cout << vec[i][j] << ' ';
            
        cout << '\n';
    }
}

Thank U very much. That helps a lot. Now i am working on to understand this syntax & apply it. You are doing a great job..

Member Avatar
PrimePackster
Posting Whiz in Training
252 posts since Nov 2011
Reputation Points: 10 [?]
Q&As Helped to Solve: 17 [?]
Skill Endorsements: 3 [?]
 
0
 

That still follows an older standard. The code that I posted earlier was written on VC++ 2008.

Here is some info on the Standard Template Library (the "STL"). The std::vector, as well as several other container templates, is part of the STL.

Thanks for helping me...:D

Question Answered as of 2 Years Ago by Narue, Fbody, frogboy77 and 1 other
You
This question has already been solved: Start a new discussion instead
Post:
Start New Discussion
View similar articles that have also been tagged: