Dynamic Array Woes

Started by
15 comments, last by Zahlman 17 years ago
Fairly new to C++ and want to make an Array that I can add new elements, take some away, rearrange the order and such. With some tutorials I have read, none seem to be able to explain how I do this though. I have an inkling that these are properties of another concept (vector, map?) Tar
Advertisement
Questions:
1) Does the data have to be in a contiguous memory block?
2) From where do you want to remove elements? (Front, back or anywhere?)
Quote:Original post by ConorH
Fairly new to C++ and want to make an Array that I can add new elements, take some away, rearrange the order and such. With some tutorials I have read, none seem to be able to explain how I do this though. I have an inkling that these are properties of another concept (vector, map?)

Tar

Arrays are usually static in size - that is, once you create the array, it stays at the size that you created it. It is possible to flag items in the array as in-use or not, but technically, they are still there. You probably want to look into something called a linked list. A linked list will allow you to add and remove items in the list, as well as reorder them.

A std::vector or std::list is probably what you want. Check out these FAQs as well for pertinent information and some more details.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Moved to For Beginners.
Im using my vector/list to store SDL_Surface* but when I try and return the reference for it, it gives me an error


std::list<SDL_Surface*> im;

int cSprite::LoadImage(const char* _file)
{
//Add the loaded file onto vector list
im.push_back(Gfx.LoadImage(_file));
return im.end();
}

1>.\engine.cpp(111) : error C2440: 'return' : cannot convert from 'std::list<_Ty>::_Iterator<_Secure_validation>' to 'int'
1> with
1> [
1> _Ty=SDL_Surface *,
1> _Secure_validation=true
1> ]


I want to be able to get the reference from the function though :(
Any ideas? I can see that Im doing something wrong here
edit: I assume that references arent in the form of int's then. Im used to referencing array elements with ints/int literals from when I used DarkBasic
Quote:Original post by ConorH
std::list<SDL_Surface*> im;

int cSprite::LoadImage(const char* _file)
{
//Add the loaded file onto vector list
im.push_back(Gfx.LoadImage(_file));
return im.end();
}
Two problems are immediately evident here:

1. list::end() returns an iterator that points 'one past the end' of the list. It appears you want to access the last item added to the list; to do so, use list::back().

2. The function return type is int, but you're trying to return an SDL_Surface*.

I recommend fixing these errors and then re-posting your code (as there are some other areas where improvements could be made).
If list::end()/back() returns an iterator for the last element, how come its returning the value of it (SDL_Surface*)?

Im trying to abstract the use of SDL_Surfaces, and just use image numbers for instance, so that's why I want to return the iterator
Quote:Original post by ConorH
If list::end()/back() returns an iterator for the last element, how come its returning the value of it (SDL_Surface*)?


list::end() returns an iterator that is after the last valid iterator. It doesn't have an associated value and should not be dereferenced. If the iterator is bidirectional (it is, for a list), you may decrement a copy of end() to reach the last element.

list::back() returns a reference to the last element: it's neither an iterator nor a value.

Either way, an iterator is not an integer, so a function which has an int return type should not and cannot return an iterator.

EDIT: an alternative:

// Use integers as identifiers. They are recycled.template<typename T>class IDMap{  std::vector<T*> elements;  std::vector<int> free_indices;public:  T& operator[](int i)  {    assert (i >= 0);    assert (i < elements.size());    assert (elements);    return *elements;  }  int add(T& element)   {    if (free_indices.empty())     {      elements.push_back(&element);      return elements.size() - 1;    }    else     {      int index = free_indices.back();      free_indices.pop_back();      elements[index] = &element;      return index;    }  }  void remove(int index)  {    assert (i >= 0);    assert (i < elements.size());    assert (elements);    elements[index] = 0;    free_indices.push_back(index);  }};


This object is responsible for translating indices into object pointers and vice versa, and may be used as part of a greater system which only lets the indices be public.

Of course, wrapping the texture in an object would be a much better way of abstracting this.
K, confused now. 2 Questions,
What's the diffrence between reference and iterator?
and
How can I return an iterator?

This topic is closed to new replies.

Advertisement