Array Trouble

I am having trouble when assigning values from one array to a multidimensional array. I am getting a AccessViolationException.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    	// Create space
    nSamples = Header.Data_Hdr.Len / Header.Fmt_Chunk.BytesPerSam;
    Sample = new short int[nSamples];

    	// Read wave
    inf.read((char*)Sample, Header.Data_Hdr.Len);
   	inf.close();

		// Frame length, frame period & number of frames
	int FrmLen = 160;	//20ms of audio
    int FrmPer = 80;	//10ms shift
	int nFrms = (nSamples - FrmPer) / FrmPer;

		// Store frames to array
	frames = new float*[nFrms]; //[FrmLen];
	for(int i=0; i<FrmLen; i++)
	{
		frames[i] = new float[FrmLen];
	}
    for(int k = 0; k < nFrms; k++) 
	{
		//short int* s = Sample;
		for(int n = 0; n < FrmLen; n++)
		{
			frames[k][n] = Sample[n]; // This is where I am having
                }                                 // the trouble.
	}


frames[][] is defined in my header as float** frames.
As you can see I also tried creating a short int* s = Sample and cycling through that, but I get the same problem.

Any help would be greatly appreciated
I'm guessing FrmLen > nSamples. If that's the case, then Sample[n] is trying to access beyond the end of the buffer, which may cause an access violation.
I had to change that for loop to:

1
2
3
4
5
6
7
8
9
		//short int* s = Sample;
		for(int n = 0; n < FrmLen; n++)
		{
			if(k!=0)
			{
				frames[k][n] = Sample[n +(k * FrmLen)];
			}
			else frames[k][n] = Sample[n];
		}


but this was to fix another problem that it was going to put the same information into each frame.

I am wondering if it is because I may be running out of memory?

nFrames = 29619 and frmLen = 160 so.. frames[29619][160]

thanks Disch but I am pretty sure FrmLen should always be less, but I will look at it more.
Well an access violation is a pretty clear indicator of an out-of-bounds array access.

You are not stepping out of bounds on frames, so you must be stepping out of bounds on Sample.

Let's put this another way: How big is Sample? I can't tell from the above code. (EDIT: actually I can... give me a bit and I'll review again. Sorry about that)


Also... change this:

1
2
3
4
5
6
7
8
for(int n = 0; n < FrmLen; n++)
{
//    if(k!=0)   // get rid of all this crap
//    {
        frames[k][n] = Sample[n +(k * FrmLen)];  // just do this
//    }
//    else frames[k][n] = Sample[n];
}


Don't try to micro-optimize like that. The computer can do math like it's nothing -- conditionals are usually slower. Not to mention that needlessly makes your code larger.


EDIT2:

Wait a minute, you're spinning on FrmLen, but you're allocating based on FrmPer. That's got to be the problem.

What are FrmPer / FrmLen? Like what do they represent? FrmLen seems like it'd be the length of a frame, which make sense, but then what does FrmPer do?

This line:
int nFrms = (nSamples - FrmPer) / FrmPer;

I wonder if that should be this instead:

int nFrms = (nSamples - FrmLen) / FrmLen;

I'm 99% sure that would fix the problem.

But you'd still have a problem if nSamples is less than FrmLen.
Last edited on
Cheers Disch,

I had just realised the if statement was completely unnecessary after posting that...

I agree now that it is to do with the Sample[] reaching out-of-bounds, will keep trying to figure out where I am going wrong.

Cheers for your help.

P.S. I have only been using C and C++ for about 2 months and still getting to grips with it, would be much more comfortable with Java or C# :s

EDIT: FrmLen is the length of a frame which is 160 samples
FrmPer is the shift of the next frame eg.

1st Frame = Sample[0 .. 159]
2nd Frame = Sample[79 .. 239] etc

also if helpful there are nSamples = 2369600

EDIT2: therefor nFrms = (2369600 - 80)/ 160 = 29619
therefor nFrms = (2369600 - 80)/ 80 = 29619

bad maths that might be my problem ha ha

Last edited on
FIXED CODE:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    	// Create space
    nSamples = Header.Data_Hdr.Len / Header.Fmt_Chunk.BytesPerSam;
    Sample = new short int[nSamples];

    	// Read wave
    inf.read((char*)Sample, Header.Data_Hdr.Len);
    inf.close();

			// Frame length, frame period & number of frames
    int FrmLen = 160;	//20ms of audio
    int FrmPer = 80;	//10ms shift
    int nFrms = (nSamples - FrmPer) / FrmPer;

		// Store frames to array
	frames = new float*[nFrms]; //[FrmLen];
	for(int i=0; i<nFrms; i++)
	{
		frames[i] = new float[FrmLen];
	}
        for(int k = 0; k < nFrms; k++) 
	{
		short int* s = Sample;
		for(int n = 0; n < FrmLen; n++)
		{
			frames[k][n] = s[n +(k * FrmPer)];
		}
	}


Now works. Also surprised how fast such large arrays can be processed.
Time to perform windowing and pre-emphasis on each frame <sigh>...

Thanks for the help Disch, much appreciated
Topic archived. No new replies allowed.