CodeGuru Forums -
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic Newsletters VB Forums Developer.com


Newest CodeGuru.com Articles:

  • Installing SQL Server 2008
  • Writing UDFs for Firebird Embedded SQL Server
  • [Updated] Shutdown Manager
  • Building Windows Azure Cloud Service Applications with Azure Storage and the Azure SDK

  • Search CodeGuru:
     



    Go Back   CodeGuru Forums > Visual C++ & C++ Programming > C++ (Non Visual C++ Issues)
    FAQ Members List Calendar Search Today's Posts Mark Forums Read

    C++ (Non Visual C++ Issues) Ask or answer C and C++ questions not related to Visual C++. This includes Console programming, Linux programming, or general ANSI C++.

    Reply
     
    Thread Tools Search this Thread Rate Thread Display Modes
      #1    
    Old September 2nd, 2005, 08:31 PM
    Corporal Kindel Corporal Kindel is offline
    Junior Member
     
    Join Date: Sep 2005
    Posts: 10
    Corporal Kindel is an unknown quantity at this point (<10)
    Declaring & initializing dynamic array of pointers question?

    Hello

    First time trying out the Code Guru forums, so here it goes. I just completed a first quarter course in Java, and now I’m jumping into a second quarter course in C++. (this is a big jump, first time using pointers & dynamic arrays) I’ve been working on this project for 8 hours now, and I’m stuck at this part in which I need to convert a static array to a dynamic array of pointers, not sure what I’m doing wrong here, hoping someone could point out exactly what it is I’m doing wrong & point me in the right direction as far as fixing it. I got the following problem:


    Header area

    int MaxDBsize;

    struct InvRec
    {
    int Part ID;
    float Price;
    };

    typedef InvRec *InvRecptr;
    typedef InvRecptr arr[]; //line 23

    void main()
    {
    ...
    Cin >> MaxDBsize;
    arr index = new arr[MaxDBsize] //line73
    ...
    }



    1) I get the following error codes:
    error C2057 ‘<unknown>:’ missing subscript
    and
    error C2440 ‘initializing’: cannot convert from ‘struct InvRec *(*)[1]’ to ‘struct InvRec *[]’

    2) among the many things I tried to fix it was changing line 23 to:
    arr InvRecptr[];
    but I get the following errors:
    : missing ';' before identifier 'InvRecptr'
    : missing storage-class or type specifiers
    : fatal error C1004: unexpected end of file found

    In the first case my reasoning was: declare arr as an array type of inventory record pointers, on line 23, and initialize index (line 73) as an instance of dynamic arr type with a size (MaxDBsize) entered by the user input (cin). I don’t know exactly why this approach fails.

    In case 2 I tried declaring a variable, arr, as an array of inventory records, and initializing it in line 73, otherwise same reasoning as above.

    So, what am I doing wrong, and how do I fix it? before I rip the rest of my hair out’ve my head.
    Reply With Quote
      #2    
    Old September 2nd, 2005, 08:50 PM
    Darth Hacker Darth Hacker is offline
    Member
     
    Join Date: Aug 2005
    Posts: 115
    Darth Hacker is on a distinguished road (40+)
    Re: Declaring & initializing dynamic array of pointers question?

    Please don't pull your hair out!

    Change MaxDBsize from int to const int. That will eliminate error C2057. Next, get rid of the typedef statements and replace this line:
    Code:
    arr index = new arr[MaxDBsize];
    with this line:
    Code:
    InvRec* index = new InvRec[MaxDBsize];
    That should get rid of error C2440. You will also get a compiler error with Cin. It needs to be cin (all lowercase).
    Reply With Quote
      #3    
    Old September 3rd, 2005, 11:31 AM
    Andreas Masur Andreas Masur is offline
    Moderator
    Power Poster
     
    Join Date: May 2000
    Location: KY, USA
    Posts: 18,610
    Andreas Masur has a brilliant future (2000+)Andreas Masur has a brilliant future (2000+)Andreas Masur has a brilliant future (2000+)Andreas Masur has a brilliant future (2000+)Andreas Masur has a brilliant future (2000+)Andreas Masur has a brilliant future (2000+)Andreas Masur has a brilliant future (2000+)Andreas Masur has a brilliant future (2000+)Andreas Masur has a brilliant future (2000+)Andreas Masur has a brilliant future (2000+)Andreas Masur has a brilliant future (2000+)
    Re: Declaring & initializing dynamic array of pointers question?

    Is there any special reason why you dyanmically need to allocate? This isn't usually necessary in C++, take a look at the following introduction to the 'vector' class...which is the common way of dealing with arrays...
    __________________
    Ciao, Andreas

    "Software is like sex, it's better when it's free." - Linus Torvalds


    Article(s): Allocators (STL) Function Objects (STL)
    Reply With Quote
      #4    
    Old September 3rd, 2005, 12:50 PM
    Paul McKenzie Paul McKenzie is offline
    Elite Member
    Power Poster
     
    Join Date: Apr 1999
    Posts: 20,402
    Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)
    Re: Declaring & initializing dynamic array of pointers question?

    Quote:
    Originally Posted by Corporal Kindel
    Hello

    First time trying out the Code Guru forums, so here it goes. I just completed a first quarter course in Java, and now I’m jumping into a second quarter course in C++.
    Oh, oh. The advice I can give you is this -- Java isn't C++. Keep that in mind, and you'll do OK. Too many try to code C++ using Java techniques, making a mess of their C++ programs in doing so.
    Quote:
    I’ve been working on this project for 8 hours now, and I’m stuck at this part in which I need to convert a static array to a dynamic array of pointers,
    You are trying to create a "dynamic" array of struct's, not pointers.
    Quote:
    not not sure what I’m doing wrong here, hoping someone could point out exactly what it is I’m doing wrong & point me in the right direction as far as fixing it.
    C++ has the standard vector class. There is no need to do this using pointers.

    Also, I thnk you should retake the class with better teacher and/or course material. Why? This:
    Code:
    void main()
    This is incorrect C++. The main function returns an int. It is not "void main()", it is "int main()". See the many threads on this, including the recent one in the non-Visual C++ section. Once a teacher writes "void main()" instead of "int main()", it's time to get another teacher.

    http://www.parashift.com/c++-faq-lit....html#faq-29.3

    Also, don't type your code into the message window. Copy and paste it in the CodeGuru message window from your code editor. The reason is that there is no way for someone to know whether that typo error is the reason for compiler errors or not. For example:
    Code:
    Cin
    Don't you mean:
    Code:
    cin
    ?

    As to your code:
    Code:
    #include <iostream>
    
    int MaxDBsize;
    struct InvRec
    {
        int PartID;
        float Price;
    };
    
    typedef InvRec *InvRecptr;
    
    int main()
    {
        InvRecptr arr;
        std::cin >> MaxDBsize;
        arr = new InvRec[MaxDBsize];
        delete [] arr;
    }
    Now, the same thing using vector:
    Code:
    #include <iostream>
    #include <vector>
    
    int MaxDBsize;
    struct InvRec
    {
        int PartID;
        float Price;
    };
    
    typedef std::vector<InvRec> InvRecArray;
    
    int main()
    {
        InvRecArray arr;
        std::cin >> MaxDBsize;
        arr.resize( MaxDBSize );
    }
    Note that there is no dynamic allocation on your part. This is all handled by the vector class. Also, note the lack of pointers.

    On a side note, teaching pointers and dynamic allocation before teaching vector is IMO the wrong approach to teaching C++. Even the author of the language, Stroustrup, plus many books ("Accelerated C++" for example), also recommend that teaching the student standard classes should be emphasized first instead of hard to use pointers:

    http://www.research.att.com/~bs/new_learning.pdf

    The idea is to get the programmer into writing useful, bug-free programs as quicky as possible. To do this, you introduce them to things such as string classes instead of char arrays and pointers, vectors instead of new[]/delete[], etc. Pointers and dynamic allocation are necessary, but they are unnecessary for purposes of creating dynamic arrays.

    Regards,

    Paul McKenzie
    Reply With Quote
      #5    
    Old September 3rd, 2005, 01:24 PM
    cilu's Avatar
    cilu cilu is offline
    Moderator/Reviewer/MS MVP
    Power Poster
     
    Join Date: Oct 2002
    Location: Timisoara, Romania
    Posts: 13,400
    cilu has a reputation beyond repute (3000+)cilu has a reputation beyond repute (3000+)cilu has a reputation beyond repute (3000+)cilu has a reputation beyond repute (3000+)cilu has a reputation beyond repute (3000+)cilu has a reputation beyond repute (3000+)cilu has a reputation beyond repute (3000+)cilu has a reputation beyond repute (3000+)cilu has a reputation beyond repute (3000+)cilu has a reputation beyond repute (3000+)cilu has a reputation beyond repute (3000+)
    Re: Declaring & initializing dynamic array of pointers question?

    [ moved thread ]
    __________________
    Marius Bancila
    Home Page | Blog
    My CodeGuru articles

    My latest articles: A TR1 Tutorial: array, tuple, unordered containers, random number generators, regex, smart pointers
    Customizable alert window

    Try my VSBuildStatus add-in for Visual Studio 2005, 2008 & 2010 (v1.1).
    I do not offer technical support via PM or e-mail. Please use vbBulletin codes.
    Reply With Quote
      #6    
    Old September 3rd, 2005, 03:07 PM
    Corporal Kindel Corporal Kindel is offline
    Junior Member
     
    Join Date: Sep 2005
    Posts: 10
    Corporal Kindel is an unknown quantity at this point (<10)
    Re: Declaring & initializing dynamic array of pointers question?

    Hello:

    Thanks for all the help guys. Well the reason I didn't use vectors is that we haven't got to that point yet in the book. I'm sure we'll probably get to that point sometime in the future, in this class or some other class. The textbook we're using is Data Structures and other objects using C++ (Main, Savitch), and chapter 4 is dynamic arrays and pointers. The first project is to convert a static array problem to a dynamic array of pointers & manipulate the functions that way (move pointers instead of Data items). The instuctor provided the base program and we have to "change" it. You're right, should've copied and pasted instead of writing out the appropriate section (it was cin instead of Cin).

    I now got the declaration and the initialization of the Array to work using the first posters suggestion, thanks btw. But, I guess you're right, it's a dynamic array of structures and not pointers, it needs to be a dynamic array of pointers though. I got another typedef definition under the header, which is:
    typedef InvRecptr * indexarr // pointer to a dynamic array of inventory record pointers.
    I tried to change my line 73 index initialization to:

    InvRec* index = new InvRecptr[MaxDBsize];

    (In order to create a dynamic array of pointers) but I get the following error code:
    : error C2440: 'initializing' : cannot convert from 'struct InvRec ** ' to 'struct InvRec *'
    Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

    I’m just starting out with C++ now, so I’m not up with these error codes at all yet. From what I interpret, somehow, using the above initialization, the index (which is an inventory record pointer type) is pointing to a double pointer array (**) of inventory records? I don’t understand how the double pointer ** error is cropping up and/or creeping into the initialization?

    There is a second problem I am trying to fix .... I altered all the remaining function parameters, after using the new index array initialization (which may not be the right definition, since it’s an array of structures) of:

    InvRec* index = new InvRecptr[MaxDBsize];

    .... which is this structure type error. It involves the following two functions (which I copied and pasted):


    void readrec (InvRec*& rec) //line89
    /*Pre: Input available as expected.
    Post: Record rec filled with input data.*/
    {
    int x;
    float y;
    //InvRec z;

    int *xptr;
    float *yptr;

    cin >> x;
    cin >> y;

    //cin >> rec.PartID;
    //cin >> rec.Price;

    //rec.PartID =x;
    //rec.Price=y;

    xptr->rec.PartID; //line 109
    yptr->rec.Price; //line 110

    *xptr = x;
    *yptr = y;

    cout << "1 test de-ref xptr: " << *xptr << endl; //test to see what is stored
    cout << "2 test de-ref yptr: " << *yptr << endl; //test to see what is stored

    };



    void readdata (arr DB, int & size)
    /*Pre: DB is an array of MAXDBSIZE inventory records.
    Post: 0<=size<=MAXDBSIZE and the first "size" elements of the DB array are
    filled with input data.*/
    {
    void readrec (InvRec*&);
    char YN;
    int *sizeptr = &size;

    size = 0;
    do
    {
    cout << "More data (Y/y/N/n)? " << endl;
    cin >> YN;
    if ((YN == 'Y') || (YN == 'y'))
    if (size < MaxDBsize) (readrec (DB[size++]); //line 136
    << DB[size] << endl;
    else cout << "Database size may not exceed "<< MaxDBsize << endl;
    else if ((YN != 'N') && (YN != 'n')) cout << "Please answer Y/y/N/n. ";
    }
    while ((YN != 'N') && (YN != 'n'));
    //DB = new arr[size];

    };



    All the commented-out stuff are things that I’ve tried & failed with. In the do-while loop of the readdata function, line 136, I’m passing arr DB as an actual parameter to the readrec function, line 89, it’s one element of an array of pointers (at least that’s what I want), but the problem is, I think, that I’m trying to simultaneously do two things in one function, namely: 1) read a structure record composed of a PardID and Price (read record), and 2) while reading in the structure element using user input, simultaneously make it a pointer, so that it doesn’t mismatch with the Formal function parameter, line 89. I may not be approaching it correctly. But anyway, I get the following error codes:

    : error C2227: left of '->rec' must point to class/struct/union //line 109
    : error C2228 left of '.PartID' must have class/struct/union type //line 109
    : error C2227: left of '->rec' must point to class/struct/union //line 110
    : error C2228: left of '.Price' must have class/struct/union type //line 110

    Is it that the class/struct/union type is an array element, a referance pointer Parameter (InvRec*& rec), instead of (InvRec& rec)? But I want it to be an array of pointers so how would I both do: 1) user-input the rec data structure element and 2) maintain an array of pointers (without having to completely change the array type)? Or is it that I just have a simple syntax error in lines 109 & 110, and if so what is the syntax?

    Thanks again for all the help,
    rk

    But the way, what area did they move this thread to? I assumed it was visual C++ programming because that is the C++ program type that we're using in the class.
    Reply With Quote
      #7    
    Old September 3rd, 2005, 04:57 PM
    Paul McKenzie Paul McKenzie is offline
    Elite Member
    Power Poster
     
    Join Date: Apr 1999
    Posts: 20,402
    Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)
    Re: Declaring & initializing dynamic array of pointers question?

    Quote:
    Originally Posted by Corporal Kindel
    The first project is to convert a static array problem to a dynamic array of pointers & manipulate the functions that way (move pointers instead of Data items).
    There is something wrong with the assignment. There is no such thing as turning a static array of T to an dynamic array of T*. You can't do this. That's like turning a truck into a pancake. They are not the same thing, and this is why you are having problems.

    You may have misunderstood the assignment. The only thing that can be converted is an array of T to a dynamic array of T. To do this, yes, you need pointers, where T* is the pointer to the first T, *(T+1) is the second T, *(T+2) is the third T, etc..

    The major reasons for T** is if you are

    1) Creating a two-dimensional array of type T dynamically

    2) You are passing a T* to a function that will initialize the T* to some value

    Are you doing any of these? If not, then your assignment, sorry to say, doesn't make sense.
    Quote:
    The instuctor provided the base program and we have to "change" it
    That's the problem, change it to what? You can't go from array of T to array of T* -- again, it doesn't make sense. This is the reason why you are getting the errors saying that you cannot go from T to T*. The instructor must have given this assignment as a joke or to waste your time (if that is actually what you're supposed to do). I hate these crap C++ courses that not only teach you the wrong things to do, it teaches you things that are not done whatsoever. Then it takes one of us to unteach all of this.
    Quote:
    it's a dynamic array of structures and not pointers, it needs to be a dynamic array of pointers though.
    Let's see what a dynamic array of pointers are:
    Code:
    T** p;
    p = new T*[10];
    for ( int i = 0; i < 10; ++i )
        p[i] = new T;
    You now have a dynamic array of pointers to T. Each T then needs to be allocated in a loop, since just creating an array of T* does not initialize each T* to anything.

    Is this what you're looking for? But it still doesn't match the original problem of array of T to a dynamic array of T. This is where it not only confuses you, it's confusing me. See the reasons for a T** earlier in my post.
    Quote:
    From what I interpret, somehow, using the above initialization, the index (which is an inventory record pointer type) is pointing to a double pointer array (**) of inventory records? I don’t understand how the double pointer ** error is cropping up and/or creeping into the initialization?
    The way C++ (and C) interprets pointers is as follows:
    Quote:
    T a[5] is an array of 5 T objects

    a[0] == *(a+0)
    a[1] == *(a+1)
    a[2] == *(a+2)
    a[3] == *(a+3)
    a[4] == *(a+4)
    Note how an array is analogous to using only one "*" when using equivalent pointer syntax. Now to do the T a[5] dynamically, you do not allocate 5 pointers to T -- you allocate one pointer to T, where that pointer points to 5 items.
    Code:
    T *a;
    a = new T[5]; // for example
    If you create an array of T*, which you claim the assignment is supposed to do, then each element of the array is a T*, not a T.

    The easiest way to look at it is that the word "array" means to tack on a "*". So when you have an array of T*, you are dealing with "**" -- one "*" for the array, and the other for the T* element of each item in the array.
    Quote:
    There is a second problem I am trying to fix .... I altered all the remaining function parameters, after using the new index array initialization (which may not be the right definition, since it’s an array of structures) of:
    Fix or clarify the assignment first, before anyone can understand it. Right now, I doubt that others can get a grasp of what you're really trying to accomplish.
    Quote:
    But the way, what area did they move this thread to? I assumed it was visual C++ programming because that is the C++ program type that we're using in the class.
    There is no C++ program type. There is only one C++. Regardless of the brand of compiler you use, there is only one C++ language. If you posted your program, I could probably compile it using Borland C++ Builder, gcc, CodeWarrior, Digital Mars, etc. compilers with little to no change.

    Your code is generic C++, which is why it was moved to the non-Visual C++ section -- there is nothing in it that is specific to Visual C++, i.e. MFC, ATL or some other class library used by Visual C++. It is all plain C++.

    Regards,

    Paul McKenzie

    Last edited by Paul McKenzie; September 3rd, 2005 at 05:09 PM.
    Reply With Quote
      #8    
    Old September 3rd, 2005, 05:29 PM
    HighCommander4 HighCommander4 is offline
    Senior Member
     
    Join Date: Apr 2004
    Location: Canada
    Posts: 1,268
    HighCommander4  is a jewel in the rough (300+)HighCommander4  is a jewel in the rough (300+)HighCommander4  is a jewel in the rough (300+)HighCommander4  is a jewel in the rough (300+)
    Re: Declaring & initializing dynamic array of pointers question?

    Quote:
    Originally Posted by Corporal Kindel
    I now got the declaration and the initialization of the Array to work using the first posters suggestion, thanks btw. But, I guess you're right, it's a dynamic array of structures and not pointers, it needs to be a dynamic array of pointers though. I got another typedef definition under the header, which is:
    typedef InvRecptr * indexarr // pointer to a dynamic array of inventory record pointers.
    I tried to change my line 73 index initialization to:

    InvRec* index = new InvRecptr[MaxDBsize];

    (In order to create a dynamic array of pointers) but I get the following error code:
    : error C2440: 'initializing' : cannot convert from 'struct InvRec ** ' to 'struct InvRec *'
    Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

    I’m just starting out with C++ now, so I’m not up with these error codes at all yet. From what I interpret, somehow, using the above initialization, the index (which is an inventory record pointer type) is pointing to a double pointer array (**) of inventory records? I don’t understand how the double pointer ** error is cropping up and/or creeping into the initialization?
    Is InvRecptr a typedef for InvRec*? All these typedefs make your code really confusing. Anyways, assuming that InvRecptr is a typedef for InvRec*, the problem is that creating a dynamic array using new[] returns a pointer to the first element of the array that was created. Here is the syntax for using the new[] operator:

    Code:
    type* identifier = new type[array_size];
    So if you are creating an array of InvRec objects ("type" is InvRec), then new[] will return a pointer-to-InvRec (InvRec*). This is the correct way to create a dynamic array of InvRec objects:

    Code:
    // option A - creating an array of InvRec objects
    InvRec* index = new InvRec[MaxDBSize];
    If, on the other hand, you are creating an array of pointers to InvRec objects ("type" is InvRec*), then new[] will return a pointer-to-pointer-to-InvRec (InvRec**). This is the correct way to create a dynamic array of pointers-to-InvRec

    Code:
    // option B - creating an array of pointers-to-InvRec
    InvRec** index = new InvRec*[MaxDBSize];
    So read the assignment specifiecations again and see whether it says you need to create an array of InvRec objects (option A) or an array of pointers-to-InvRec (option B). Mixing the two together like you were trying won't work:

    Code:
    InvRec* index = new InvRec*[MaxDBSize];
    // doesn't work - new[] returns an InvRec**
    // and you can't assign an InvRec** to an InvRec*
    __________________
    Si fractum non sit, noli id reficere.
    Reply With Quote
      #9    
    Old September 3rd, 2005, 06:08 PM
    Darth Hacker Darth Hacker is offline
    Member
     
    Join Date: Aug 2005
    Posts: 115
    Darth Hacker is on a distinguished road (40+)
    Re: Declaring & initializing dynamic array of pointers question?

    Take a look at these code snippets.

    Statically allocated array of objects:
    Code:
    struct T
    {
    	int Data1;
    	double Data2;
    };
    
    T Arr[10];
    
    int main(int argc, char* argv[])
    {
            //initialization
    	for (int i=0; i<10; i++)
    	{
    		Arr[i].Data1 = 1;
    		Arr[i].Data2 = 1.2345;
    	}
    
    	return 0;
    }
    Statically allocated array of pointers:
    Code:
    struct T
    {
    	int Data1;
    	double Data2;
    };
    
    T* Arr[10];
    
    int main(int argc, char* argv[])
    {
    	int i;
    
    	//initialization
    	for (i=0; i<10; i++)
    	{
    		Arr[i] = new T;
    		Arr[i]->Data1 = 1;
    		Arr[i]->Data2 = 1.2345;
    	}
    
    	//cleanup
    	for (i=0; i<10; i++)
    		delete Arr[i];
    
    	return 0;
    }
    Dynamically allocated array of objects:
    Code:
    struct T
    {
    	int Data1;
    	double Data2;
    };
    
    int main(int argc, char* argv[])
    {
    	int i;
    
    	//initialization
    	T* Arr = new T[10];
    
    	for (i=0; i<10; i++)
    	{
    		Arr[i].Data1 = 1;
    		Arr[i].Data2 = 1.2345;
    	}
    
    	//cleanup
    	delete[] Arr;
    
    	return 0;
    }
    Dynamically allocated array of pointers (the hard way):
    Code:
    struct T
    {
    	int Data1;
    	double Data2;
    };
    
    int main(int argc, char* argv[])
    {
    	int i;
    
    	//initialization
    	T** Arr = new T*[10];
    
    	for (i=0; i<10; i++)
    	{
    		Arr[i] = new T;
    		Arr[i]->Data1 = 1;
    		Arr[i]->Data2 = 1.2345;
    	}
    
    	//cleanup
    	for (i=0; i<10; i++)
    		delete Arr[i];
    
    	delete[] Arr;
    
    	return 0;
    }
    Using C++ containers (the preferred way):
    Code:
    struct T
    {
    	int Data1;
    	double Data2;
    
    	T(int D1 = 0, double D2 = 0){Data1 = D1; Data2 = D2;}
    };
    
    int main(int argc, char* argv[])
    {
    	vector<T> Arr;
    
    	//initialization
    	for (int i=0; i<10; i++)
    		Arr.push_back(T(1, 1.2345));
    
    	return 0;
    }
    I agree that vectors et al should be taught first. But my experience with instructors is that they want to teach you the hard way first as motivation for the need of the easy way. If you are learning programming from a theoretical standpoint, that's probably the right approach. But if you are in the real world writing software for a customer, then learn the easy way first.
    Reply With Quote
      #10    
    Old September 3rd, 2005, 06:52 PM
    HighCommander4 HighCommander4 is offline
    Senior Member
     
    Join Date: Apr 2004
    Location: Canada
    Posts: 1,268
    HighCommander4  is a jewel in the rough (300+)HighCommander4  is a jewel in the rough (300+)HighCommander4  is a jewel in the rough (300+)HighCommander4  is a jewel in the rough (300+)
    Re: Declaring & initializing dynamic array of pointers question?

    Quote:
    Originally Posted by Corporal Kindel
    : error C2227: left of '->rec' must point to class/struct/union //line 109
    : error C2228 left of '.PartID' must have class/struct/union type //line 109
    : error C2227: left of '->rec' must point to class/struct/union //line 110
    : error C2228: left of '.Price' must have class/struct/union type //line 110
    These errors are from the readrec() function. I'm not exactly sure what you are trying to do in the readrec() function, but if your objective is simply to input data into an InvRec structure, it's way overcompikcated. These simple 2 lines of code would suffice:

    Code:
    void readrec (InvRec*& rec) //line89
    /*Pre: Input available as expected.
    Post: Record rec filled with input data.*/
    {
        cin >> rec->PartID;
        cin >> rec->Price;
    }
    Also, is there a reason why this function needs to take a reference to a pointer-to-Invrec? Wouldn't it be simpler to pass a reference to an InvRec object?

    Code:
    void readrec (InvRec& rec) //line89
    /*Pre: Input available as expected.
    Post: Record rec filled with input data.*/
    {
        cin >> rec.PartID;
        cin >> rec.Price;
    }
    If you correct this and you are still experiencing problems with the readdata() function, please post a piece of complete code (including all the typedefs you are using so I can understand your code) and I'll take a look at it.
    __________________
    Si fractum non sit, noli id reficere.

    Last edited by HighCommander4; September 3rd, 2005 at 06:57 PM.
    Reply With Quote
      #11    
    Old September 3rd, 2005, 07:33 PM
    Corporal Kindel Corporal Kindel is offline
    Junior Member
     
    Join Date: Sep 2005
    Posts: 10
    Corporal Kindel is an unknown quantity at this point (<10)
    Re: Declaring & initializing dynamic array of pointers question?

    Thanks for all your help guys. I'm going to go through my whole program from top to bottom again, and take in what everyone has said. You guys helped me understand quite a bit what was going on behind-the-scenes that I didn't fully understand before. If I still have problems, I'll post the whole enchilada tomorrow night .. been at this for about 16 hours now for 3/4 days. Thank god it's not due until the 12th, so I still got plenty of time to work on it. My instructor has been in China for a week now, so the class hasn't been able to contact him for office hours, email help ... that's mainly why I posted my questions on this forum, and I'm glad I did so.
    Reply With Quote
      #12    
    Old September 3rd, 2005, 11:18 PM
    Corporal Kindel Corporal Kindel is offline
    Junior Member
     
    Join Date: Sep 2005
    Posts: 10
    Corporal Kindel is an unknown quantity at this point (<10)
    Re: Declaring & initializing dynamic array of pointers question?

    Well I finally got the program to pass the compiler, unfortunately it failed in the link phase during build. Unfortunately the link error doesn't point me out an exact line number for my to narrow down the problem. The error code & still-in-work program (getting close) is as follows:

    link errors:

    Linking...
    : error LNK2001: unresolved external symbol "void __cdecl sortbyPartID(struct InvRec * *,int)" (?sortbyPartID@@YAXPAPAUInvRec@@H@Z)
    : error LNK2001: unresolved external symbol "void __cdecl printdata(struct InvRec * *,int)" (?printdata@@YAXPAPAUInvRec@@H@Z)
    : error LNK2001: unresolved external symbol "void __cdecl readdata(struct InvRec * *,int &)" (?readdata@@YAXPAPAUInvRec@@AAH@Z)
    Debug/P1WarmUp.exe : fatal error LNK1120: 3 unresolved externals
    Error executing link.exe.

    P1WarmUp.exe - 4 error(s), 0 warning(s)

    but the compiler worked!
    my code as far as now is:


    Code:
    #include <iostream.h>
    
    int MaxDBsize;
    
    /*Type delcarations - NO MEMORY ALLOCATED (EVEN STATICALLY)*/
    struct InvRec	/*Inventory record with its fields*/
    	{
    	int PartID;
    	float Price;
    	};
    typedef InvRec *InvRecptr;	/*Inventory record pointer type*/
    typedef InvRec* arr[];
    arr index;
    typedef InvRecptr *indexarr; /* Pointer to a dynamic array of inventory record pointers*/
    
    void deallocate (indexarr & ptrs, int & size)
    
    {
    	for (int i=0; i<size; i++) delete (ptrs[i]);
    	delete ptrs;
    	ptrs = NULL;
    	size = 0;
    };
    
    void main ()
    {
    	
    	void readdata (InvRec**, int &);
    	void sortbyPartID (InvRec**, int);
    	void printdata (InvRec**, int);
    	
    	cout << "Enter a size amount for the index array: " << endl;
    	cin >> MaxDBsize;
    	InvRec** index = new InvRec*[MaxDBsize];
    	int dbsize;
    	char temp;
    
    	readdata (index, dbsize);
    	cout << "Original data:" << endl;
    	printdata (index, dbsize);
    	sortbyPartID (index, dbsize);
    	cout << "Data sorted by PartID:" << endl;
    	printdata (index, dbsize);
    	cout << "Please input a non-white space key to end the session." <<endl;
    	cin >> temp;
    };
    
    void readrec (InvRec*& rec)
    /*Pre: Input available as expected.
    Post: Record rec filled with input data.*/
    {
    	cin >> rec->PartID;
    	cin >> rec->Price;
    };
    
    void readdata (arr DB, int & size)
    /*Pre: DB is an array of MAXDBSIZE inventory records.
    Post: 0<=size<=MAXDBSIZE and the first "size" elements of the DB array are 
    filled with input data.*/
    {
    	void readrec (InvRec*&);
    	char YN;
    	size = 0;
    	do
    	{
    		cout << "More data (Y/y/N/n)? " << endl;
    		cin >> YN;
    		if ((YN == 'Y') || (YN == 'y'))
    			if (size < MaxDBsize)  
    			readrec (DB[size++]);
    			else cout << "Database size may not exceed " << MaxDBsize << endl;
    			else if ((YN != 'N') && (YN != 'n')) cout << "Please answer Y/y/N/n.  ";
    	}
    	while  ((YN != 'N') && (YN != 'n'));
    };
    
    void printrec (InvRec* rec)
    /*Pre: rec has data.
    Post: The data in rec printed out.*/
    {
    	int x;
    	float y;
    
    	int *xptr;
    	float *yptr;
    
    	xptr = &x;
    	yptr = &y;
    	
    	cout << *xptr << ' ' << *yptr << endl;
    };
    
    void printdata (arr DB, int size)
    /*Pre: 0<=size<=MAXDBSIZE and the first "size" elements of the DB array are
    inventory records containing data.
    Post: They are all printed out in the order pointed at.*/
    {
    	void printrec (InvRec*);
    	int i;
    	for (i=0; i<size; i++) printrec(DB[i]);
    };
    
    void swap (InvRec *& x, InvRec *& y)
    /*Pre: None.
    Post: The values of x and y are swapped.*/
    {
    	InvRec *temp;
    	temp = x;
    	x = y;
    	y = temp;
    };
    
    int selectsmallestPartID (arr DB, int first, int last)
    /*Pre: "first" through "last" elements of the DB array are inventory
    records containing data.
    Post: A value k is returned such that, for i ranging from first to last,
    the relation DB[k].PartID <= DB[i].PartID holds.*/
    {
    	int j, result;
    	result = first;
    	int *jptr=&j, *resultptr=&result, *firstptr=&first;
    	
    	for (j=first+1; j<=last; j++)
    		if (DB[*jptr] < DB[*resultptr]) resultptr = jptr;
    		//if (DB[j].PartID < DB[result].PartID) result = j;
    	return *resultptr;
    };
    
    void sortbyPartID (arr DB, int size)
    /*Pre: 0<=size<=MAXDBSIZE and the first "size" elements of the DB array are
    inventory records containing data.
    Post: for i ranging from 1 to size-2, the relation DB[i].PartID <= 
    DB[i+1].PartID holds.*/
    {
    	int selectsmallestPartID (arr, int, int);
    	int i, smallindex;
    	int *iptr=&i, *smallindexptr=&smallindex;
    
    	for (i=0; i<=size-2; i++)
    	{
    		smallindex = selectsmallestPartID (DB, i, size-1);
    		swap (DB[i], DB[smallindex]);
    		//swap (DB[iptr], DB[smallindexptr]);
    	};
    };
    BTW the main array in the program is no longer an array of inventory records, but is now an array of pointers to inventory records, which is what I was supposed to do for the project. I haven't as yet implemented the deollocate function, that will be my next priority as soon as I can get the basic program working correctly.

    The link error says unresolved external symbol void, what does that mean? .. the functions that it references are supposed to have a void return type, so I don't understand what is going on there? Gotta hit the sack here this program is draining & it's hard to concentrate late at night.

    Last edited by Corporal Kindel; September 4th, 2005 at 07:18 PM.
    Reply With Quote
      #13    
    Old September 4th, 2005, 03:46 AM
    SuperKoko's Avatar
    SuperKoko SuperKoko is offline
    Elite Member
    Power Poster
     
    Join Date: Feb 2005
    Location: Normandy in France
    Posts: 4,590
    SuperKoko has a brilliant future (2000+)SuperKoko has a brilliant future (2000+)SuperKoko has a brilliant future (2000+)SuperKoko has a brilliant future (2000+)SuperKoko has a brilliant future (2000+)SuperKoko has a brilliant future (2000+)SuperKoko has a brilliant future (2000+)SuperKoko has a brilliant future (2000+)SuperKoko has a brilliant future (2000+)SuperKoko has a brilliant future (2000+)SuperKoko has a brilliant future (2000+)
    Re: Declaring & initializing dynamic array of pointers question?

    The errors are not : unresolved external symbol void, but:
    unresolved external symbol "void __cdecl sortbyPartID(struct InvRec * *,int)" (?sortbyPartID@@YAXPAPAUInvRec@@H@Z), etc...
    It means that the function : void sortbyPartID (InvRec**, int) is imported from the module, but is not defined in any module.
    I suppose that it may be due to the difference between the declaration and the definition of the functions.

    Firstly you should change this line:
    Code:
    typedef InvRec* arr[];
    (My compiler generate an error at the next line, saying that the size of the array is unknown)

    Replace it with:
    Code:
    typedef InvRec** arr;
    You should also remove the next line:
    Code:
    arr index; // this variable is never used!
    With these corrections, my compiler compiles correctly.
    But, i suggest that you change the declarations:
    Code:
    void readdata (InvRec**, int &);
    void sortbyPartID (InvRec**, int);
    void printdata (InvRec**, int);
    Replace them by:
    Code:
    void readdata (arr, int &);
    void sortbyPartID (arr, int);
    void printdata (arr, int);
    It is better if you need to modify the typedef of arr.

    If it does not work, try to put the function declarations outside the main function (i remember that once, i had a bug with a compiler which don't mangled function name in local declarations).

    Finally, use int main(), not void main()

    And, please, use code tags.
    To, do so, enclose your code, with tags like that:
    [ C O D E]
    the code here
    [ / C O D E ]

    But, don't put the space characters in the tags : i just put them to avoid that the forum interpret them as real code tags.
    Note also that there is a '/' character in the closing markup.
    Reply With Quote
      #14    
    Old September 4th, 2005, 06:31 PM
    Corporal Kindel Corporal Kindel is offline
    Junior Member
     
    Join Date: Sep 2005
    Posts: 10
    Corporal Kindel is an unknown quantity at this point (<10)
    Re: Declaring & initializing dynamic array of pointers question?

    Ok, finally got my program to compile & build, unfortunately, I get the following error at runtime (the program stops during runtime with an exception, and clicking on debug points me to the following program snipit which I copied and pasted below). The error code pointer points to the else n = (int) value; line near the bottom. My program is going to kill me before I'm done with it. Note: the error code program snipit that fails is not even part of my original program.

    I need to figure out what this error is (or where it's referring to in my program, which is not clearly defined). I take it that the cin >> (istream operator) is failing in my program somewhere? Is it possible to determine exactly where the istream operator is failing in my program & why? Also, why is the istream operator failing when I have the library #include <iostream.h> correctly included in the header of my program?


    Code:
    /***
    * istrint.cpp - definitions for istream class operaotor>>(int) member functions
    *
    *       Copyright (c) 1991-1997, Microsoft Corporation. All rights reserved.
    *
    *Purpose:
    *       Definitions of operator>>(int) member function(s) for istream class.
    *       [AT&T C++]
    *
    *******************************************************************************/
    
    #include <cruntime.h>
    #include <internal.h>
    #include <stdlib.h>
    #include <limits.h>
    #include <iostream.h>
    #pragma hdrstop
    
    /***
    *istream& istream::operator>>(int& n) - extract int
    *
    *Purpose:
    *       Extract int value from stream
    *
    *Entry:
    *       n = value to update
    *
    *Exit:
    *       n updated, or ios::failbit & n=INT_MAX/INT_MIN on overflow/underflow
    *
    *Exceptions:
    *       Stream error on entry or value out of range
    *
    *******************************************************************************/
    istream& istream::operator>>(int& n)
    {
    _WINSTATIC char ibuffer[MAXLONGSIZ];
        long value;
        char ** endptr = (char**)NULL;
        if (ipfx(0))
            {
            value = strtol(ibuffer, endptr, getint(ibuffer));
            if (value>INT_MAX)
                {
                n = INT_MAX;
                state |= ios::failbit;
                }
            else if (value<INT_MIN)
            {
                n = INT_MIN;
                state |= ios::failbit;
                }
            else
                n = (int) value;
    
            isfx();
            }
    return *this;
    }

    Last edited by Corporal Kindel; September 4th, 2005 at 07:16 PM.
    Reply With Quote
      #15    
    Old September 4th, 2005, 07:06 PM
    Paul McKenzie Paul McKenzie is offline
    Elite Member
    Power Poster
     
    Join Date: Apr 1999
    Posts: 20,402
    Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)Paul McKenzie has a reputation beyond repute (3000+)
    Re: Declaring & initializing dynamic array of pointers question?

    This is incorrect:
    Code:
    #include <iostream.h>
    The standard ANSI C++ header is <iostream>, not <iostream.h>. That's the first thing you should fix. Then your code will (or should) exhibit the same behavior on another compiler if anyone else compiles and runs your code.

    Also, please use code tags.

    Regards,

    Paul McKenzie
    Reply With Quote
    Reply

    Bookmarks
    Go Back   CodeGuru Forums > Visual C++ & C++ Programming > C++ (Non Visual C++ Issues)


    Thread Tools Search this Thread
    Search this Thread:

    Advanced Search
    Display Modes Rate This Thread
    Rate This Thread:

    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 On
    HTML code is Off
    Forum Jump


    All times are GMT -5. The time now is 04:21 PM.



    Acceptable Use Policy

    internet.comMediabistrojusttechjobs.comGraphics.com

    WebMediaBrands Corporate Info


    Advertise | Newsletters | Feedback | Submit News

    Legal Notices | Licensing | Permissions | Privacy Policy


    Powered by vBulletin® Version 3.7.3
    Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
    Copyright WebMediaBrands Inc. 2002-2009