Jump to content
  • Advertisement
Sign in to follow this  
leet bix

"Vector subscript out of range" error

This topic is 3339 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've been getting this odd error on my DirectX app, first, I create an array of LPCSTRing's (this is just a character format incase you haven't encountered if before), and fill it like so
	LPCSTR cCubeMapDirectories[9];
	cCubeMapDirectories[0] = "Media/LightProbes/uffizi_cross.dds";
	cCubeMapDirectories[1] = "Media/LightProbes/beach_cross.dds";
	cCubeMapDirectories[2] = "Media/LightProbes/building_cross.dds";
	cCubeMapDirectories[3] = "Media/LightProbes/rnl_cross.dds";
	cCubeMapDirectories[4] = "Media/LightProbes/stpeters_cross.dds";
	cCubeMapDirectories[5] = "Media/LightProbes/grace_cross.dds";
	cCubeMapDirectories[6] = "Media/LightProbes/campus_cross.dds";
	cCubeMapDirectories[7] = "Media/LightProbes/galileo_cross.dds";
	cCubeMapDirectories[8] = "Media/LightProbes/kitchen_cross.dds";

I then pass this array to the 'create' function of a skybox class like so;
hr = g_SkyBox.CreateSkyBox(g_pd3dDevice, 
							   &BackBufferDesc,
							   50,
		                       cCubeMapDirectories, 
							   "Media/Effects/SkyBox.fx");

I then copy it into a vector of LPCSTRing's in the class like so
for(int i = 0; i < sizeof(strCubeMapFilePaths); i++)
	{
		m_EnvironmentMapDirs.push_back(strCubeMapFilePaths);
	}

// the data member m_EnvironmentMapDirs is private and declared as such:

std::vector<LPCSTR> m_EnvironmentMapDirs;	// stores paths for light probes 

After this, I have a function that allows me to set the current light probe cube map based on an index passed to it, the index is also stored in a UNIT data member in the private section of the class, the function for navigating is as follows;
	/******SetEnvironmentMapByIndex*******/
	HRESULT SetEnvironmentMapByIndex(UINT uiIndex)
	{
		// make sure that the index is in the arrays range
		if(uiIndex < 0 || uiIndex > m_EnvironmentMapDirs.size())
			return E_FAIL;

		HRESULT hr;
		SAFE_RELEASE(m_pEnvironmentMap);

		IDirect3DCubeTexture9* pCubeTexture = NULL;
		hr = D3DXCreateCubeTextureFromFileEx(m_pd3dDevice, m_EnvironmentMapDirs[uiIndex], D3DX_DEFAULT, 1, 0, D3DFMT_A16B16G16R16F,
                                         D3DPOOL_MANAGED, D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR, 0, NULL,
                                         NULL, &pCubeTexture);
		
		CHECK_RESULT(hr, "Could not set environment by index");

		m_pEnvironmentMap = pCubeTexture;
		m_EnvironmentMapIndex = uiIndex;

		return hr;
	}

although, what happens when I get to the 5th element (m_EnvironmentMapDirs[4]) is that I get a debug assertion error saying "Expression: vector subscript out of range" and the debug points me here
[source lang"cpp"]
// this is in the vector file

 #if _HAS_ITERATOR_DEBUGGING
		if (size() <= _Pos)
			{
			_DEBUG_ERROR("vector subscript out of range");
			_SCL_SECURE_OUT_OF_RANGE;
			}

I don't see how I am trying to access a member of the vector outside of it's range when it's size is 9, any ideas?

Share this post


Link to post
Share on other sites
Advertisement
What is the value of sizeof(strCubeMapFilePaths)?

std::cout << sizeof(strCubeMapFilePaths) << std::endl;

Share this post


Link to post
Share on other sites
Oh wow it's saying 4, should have tested that, but really I have no idea why this is happening.

Share this post


Link to post
Share on other sites
Applying the sizeof operator to an array gives you the size of the array in bytes. If you want the number of elements, use (sizeof arr)/(sizeof arr[0]).
However, in your case, your array has decayed into a pointer. Applying the sizeof operator to a pointer gives you the size of the pointer in bytes. Which on your platform is 4.

Share this post


Link to post
Share on other sites
Thanks, I see why it was returning 4 now :) I thought that if I was to use strCubeMapFilePaths weather or not it was passed in as a pointer it would always be a pointer, nurmeous articles say that an array without the square brackets is just a pointer to the first element?
I've tried using this for loop;


for(int i = 0; i < sizeof(strCubeMapFilePaths) / sizeof(strCubeMapFilePaths[0]); i++)
{
m_EnvironmentMapDirs.push_back(strCubeMapFilePaths);
}



but it doesn't work past the first element (element 0)

Share this post


Link to post
Share on other sites
It is probably 4 because you are probably doing applying sizeof onto a pointer type (you are on a 32bit box, right?).

Can we see the defintion of "strCubeMapFilePaths" and how you initialize it?

Hint: Why not use a standard container?

edit: D'Oh, ninja'd.

Share this post


Link to post
Share on other sites
Quote:
Original post by leet bix
but it doesn't work past the first element (element 0)


Probably (can we see the definition of strCubeMapFilePaths?) because strCubeMapFilePaths is a pointer, not an array. Read Zao's post carefully.

Share this post


Link to post
Share on other sites
I've ended up just doing this instead,


hr = g_SkyBox.CreateSkyBox(g_pd3dDevice, &BackBufferDesc, 50, cCubeMapDirectories, sizeof(cCubeMapDirectories), "Media/Effects/SkyBox.fx");



just passing in sizeof(array) to the function, I assume there's a way of doing it within the function?

Share this post


Link to post
Share on other sites
You haven't read our replies to you, have you??

Not even this tiny bit:
Quote:
my humble self
(can we see the definition of strCubeMapFilePaths?)


Meh...


char *s = "asdsad"; << sizeof (s) = 4, because s is a pointer

char **s = "asdsad"; << sizeof (s) = 4, because s is a pointer
sizeof (*s) = 4, because *s is a pointer
sizeof (**s) = sizeof(char), because **s is a char
sizeof(s)/sizeof(*s) = 4/4 = 1

char s[7] = "asdsad"; << sizeof (s) = 7*sizeof (char), because s is an array
sizeof(s)/sizeof(char) = 7

(on x86 processors, pointers are generally 4 bytes (32 bits) long, on x64, they are 8 bytes (64 bits) long; in the above example, I assumed you are on a x86 architecture)

Seriously, A) read what others replied to you and B) as you are in C++, why not use containers and string of the standard library?

[Edited by - phresnel on May 4, 2009 3:05:18 AM]

Share this post


Link to post
Share on other sites
Like the previous posters, I recommend using a container class of some sort instead of a raw array. The most logical choice would probably be boost/tr1::array. Using array will eliminate the need to track the size of the array separately, and will provide other benefits as well (such as range-checking).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!