For my project I'm using an array of structs that I declared in the header file

struct City{
        string name;
        int visits;
    };
    
    City* map[200];

now when I'm trying to initialize it in a constructor, like

for (int ii=0; ii<200; ii++)
     map[ii].visits = 0;

I get an error:

left of '.visits' must have class/struct/union

Is that due to the map being a pointer? Anyone can point me in a right direction for solving this problem?

When you are doing City* map[200] , map is an array of 200 pointers to the type City. So in order to access the members of the City struct using its pointers you need to use the -> operator.

Here are the two ways you can do it:

*map[i].visits = 100 ;
// OR
map[i]->visits = 100 ;

But, even if you do so your program won't work. Why ? Because you are not allocating memory to the pointers so acutally what they are poniting to is junk i.e. memory which doesn't belong to you. Consider allocating memory to the pointer before using it in your program.

Do, to piggy back on the answer by Mr. ~s.o.s~ :mrgreen: you should probably just declare the map as City map[200]; . That would fix your problem.

I also hope this line is not in your header file. It should be in your code file only.

Do, to piggy back on the answer by Mr. ~s.o.s~ :mrgreen: you should probably just declare the map as City map[200]; . That would fix your problem.

I also hope this line is not in your header file. It should be in your code file only.

Bleh..I wrongly assumed that the project required him to dynamically allocate memory, otherwise would have told him the simple fix :D

~s.o.s~

The project will require me to dynamically allocate memory, not for this array, but for a link list I'll also need to have.

Here's what I've done for this array:

in the header file I created a pointer to the struct

City* map;

and in the constructor I did the following:

map = new City[200];
    for (int ii=0; ii<200; ii++)
     map[ii].visits = 0;

How is this solution? I believe this is how I'd be alocating memory dynamically, if I needed to. Just have City[array_size_variable]. Is this correct? Thank you for your help.

One important thing in programming is to learn to evaluate your own code by writing it down and testing it with the help of the compiler.

Does the code which you pasted give you any errors ? No, then you are right atleast for the time being. Keep experimenting and you would learn two fold than what you are learning now.

And btw, yes your code is fine for the time being.

~s.o.s~

The project will require me to dynamically allocate memory, not for this array, but for a link list I'll also need to have.

Here's what I've done for this array:

in the header file I created a pointer to the struct

City* map;

and in the constructor I did the following:

map = new City[200];
    for (int ii=0; ii<200; ii++)
     map[ii].visits = 0;

How is this solution? I believe this is how I'd be alocating memory dynamically, if I needed to. Just have City[array_size_variable]. Is this correct? Thank you for your help.

No. You probably want:

City* map[200];    // declare an array of pointers

...

    for (int ii=0; ii<200; ii++)
    {
        map[ii] = new City;    // load each pointer with a structure
    }

And btw, yes your code is fine for the time being.

It is? If so, I stand corrected. I've never seen it done that way.

No. You probably want:

City* map[200];    // declare an array of pointers

...

    for (int ii=0; ii<200; ii++)
    {
        map[ii] = new City;    // load each pointer with a structure
    }

It is? If so, I stand corrected. I've never seen it done that way.

If it is about the semantics, then yes I agree, what I presented is not array of pointers, but if going implementation wise, both the solutions are the same. But mine with less overhead since the constructor is not getting called in the loop.

Just an example of pointer being used to emulate an array...

An eg.

#include <iostream>
#include <string>
using namespace std ;

struct City
{
    string name ;
    int visit ;
} ;

int main( )
{
    cout << endl << "~s.o.s~'s method" << endl ;
    City* map = new City[3] ;
    for( int i = 0; i < 3; ++i )
    {
        cout << "Enter name: " ;
        cin >> map[i].name ;
        getchar( ) ;
    }

    for( int i = 0; i < 3; ++i )
    {
        cout << map[i].name << endl ;
    }

    cout << endl << "Mr. WaltP's method" << endl ;

    City* mapWalt[3] ;

    for( int i = 0; i < 3; ++i )
    {
        mapWalt[i] = new City ;
        cout << "Enter name: " ;
        cin >> mapWalt[i]->name ;
        getchar( ) ;
    }

    for( int i = 0; i < 3; ++i )
    {
        cout << mapWalt[i]->name << endl ;
    }

}

My output:

~s.o.s~'s method
Enter name: abc
Enter name: efg
Enter name: hij

abc
efg
hij

Mr. WaltP's method
Enter name: abc
Enter name: efg
Enter name: hij
abc
efg
hij

In the case of array of pointers, to delete the enteries, you will have to loop through the array once while in my case it would be a simple matter of using the delete[] syntax.

I can't believe you're using new without delete[].

The point of the above post not being to teach Mr. WaltP how to use new and delete, but to prove my point...;)

How are you a moderator again? Ha ha.

And how are you not a moderator again ?

The point of the above post not being to teach Mr. WaltP how to use new and delete

I don't think Mr Disney needs to be taught anything if he says he's written all those tutorials he says he has written. ;)

I figured

delete [] map;

in Destructor would take care of removing my array.

WaltP, what's the benefit of loading each pointer with structure separately?

~s.o.s~, I do test my code with compiler, it's just I'm not at the stage of getting any meaningful results out of the project - but since I'm just learning it makes sense to write some extra functions to test intermediate progress.

I don't think Mr Disney needs to be taught anything if he says he's written all those tutorials he says he has written. ;)

Oh, I definitely nead to be taught. I am actually very weak on C++. C is my language. That's why I asked.

I figured

delete [] map;

in Destructor would take care of removing my array.

Don't figure. It will remove the pointer, but that's no guarantee it'll delete the arrays. You should use one delete for each new that was executed -- and in reverse order. Many systems will actually clean up after you, but it's bad practice to assume that cleanup will be done. So always delete every allocated buffer.

WaltP, what's the benefit of loading each pointer with structure separately?

I don't kow if there is a benefit. I haven't spent the time analyzing ~s.o.s~'s solution. On the surface, it looks good, so it depends on how you understand the the your allocation technique. Use the one you understand.

~s.o.s~, I do test my code with compiler, it's just I'm not at the stage of getting any meaningful results out of the project - but since I'm just learning it makes sense to write some extra functions to test intermediate progress.

Absolutely. Use a lot of output statements, too.

Don't figure. It will remove the pointer, but that's no guarantee it'll delete the arrays.

Its actually the reverse, delete will remove or deallocate the data pointed by new and not delete the pointer. Simply put, will send the portion of allocated memory to the free store.

You should use one delete for each new that was executed -- and in reverse order.

It is absolutely guaranteed that the memory which you allocated to an array using new[ ] will be deleted using the delete[ ]. Thats the main difference between delete and delete[ ].

The delete[] operator frees storage allocated for array objects created with new[]. The delete operator frees storage allocated for individual objects created with new.

Many systems will actually clean up after you, but it's bad practice to assume that cleanup will be done. So always delete every allocated buffer.

Yes absolutely, but the cleanup is done only when the application quits, its context destroyed and the stack frame removed. So if your application runs for a long amount of time, the memory leaks will just end up hogging system resources. Even a small amount of memory leak can cause big disasters.

Comments
Nice Post ~~ SpS
This article has been dead for over six months. Start a new discussion instead.