Jump to content

Extreame Overkill

- - - - -

This topic has been archived. This means that you cannot reply to this topic.
33 replies to this topic

#1
Ewe Loon

Ewe Loon

    Learning Programmer

  • Members
  • PipPipPip
  • 49 posts
Here is the Definitions from the header file

struct TVert

{

    float x,y,z;

    float sel;

};


typedef TVert TGrid[32][32];

typedef TGrid *PGrid;


looks simple doesn't it
TVert is 16 bytes long,
TGrid is 1024 TVerts (32 rows of 32 TVerts) should be a nice 16384 bytes
PGrid points to a TGrid

Here is the code from the function


	int x;          these are only here to show the types

	int y;

	PGrid Grid;    note Grid is pointing to the correct 

                          location by the time

                          the code below is executed



	for (x=0;x<32;x++)

		for (y=0;y<32;y++)

		{

			Grid[x][y]->x=31-Grid[x][y]->x;

			Grid[x][y]->y=31-Grid[x][y]->y;

			Grid[x][y]->z=31-Grid[x][y]->z;

		}


:mad:
It Didn't work, had a major crash , so I traced it and this is what I found

:confused:
This is what it is when compiled
You will notice i have put some comments in to help identify what its doing

x=0

:10012F21 C745EC00000000          mov [ebp-14], 00000000		

:10012F28 EB09                    jmp 10012F33


x++

:10012F2A 8B45EC                  mov eax, dword ptr [ebp-14]

:10012F2D 83C001                  add eax, 00000001

:10012F30 8945EC                  mov dword ptr [ebp-14], eax


x<32

:10012F33 837DEC20                cmp dword ptr [ebp-14], 00000020

:10012F37 0F8DA8000000            jnl 10012FE5				 


y=0

:10012F3D C745E000000000          mov [ebp-20], 00000000		

:10012F44 EB09                    jmp 10012F4F


y++

:10012F46 8B45E0                  mov eax, dword ptr [ebp-20]

:10012F49 83C001                  add eax, 00000001

:10012F4C 8945E0                  mov dword ptr [ebp-20], eax		


y<32

:10012F4F 837DE020                cmp dword ptr [ebp-20], 00000020

:10012F53 0F8D87000000            jnl 10012FE0				


x*16384

:10012F59 8B45EC                  mov eax, dword ptr [ebp-14]

:10012F5C C1E00E                  shl eax, 0E		

+grid

:10012F5F 034508                  add eax, dword ptr [ebp+08]	

y*512

:10012F62 8B4DE0                  mov ecx, dword ptr [ebp-20]		

:10012F65 C1E109                  shl ecx, 09				


1-grid[x][y].x

:10012F68 D90408                  fld dword ptr [eax+ecx]		

:10012F6B DC2DA0D90110            fsubr qword ptr [1001D9A0]		


x*16384

:10012F71 8B55EC                  mov edx, dword ptr [ebp-14]		

:10012F74 C1E20E                  shl edx, 0E				

+grid

:10012F77 035508                  add edx, dword ptr [ebp+08]	

y*512

:10012F7A 8B45E0                  mov eax, dword ptr [ebp-20]

:10012F7D C1E009                  shl eax, 09			

grid[x][y].x=

:10012F80 D91C02                  fstp dword ptr [edx+eax]		


x*16384

:10012F83 8B45EC                  mov eax, dword ptr [ebp-14]

:10012F86 C1E00E                  shl eax, 0E			

+grid

:10012F89 034508                  add eax, dword ptr [ebp+08]	

y*512

:10012F8C 8B4DE0                  mov ecx, dword ptr [ebp-20]

:10012F8F C1E109                  shl ecx, 09				


1-grid[x][y].y		// grid[x][y]+4 bytes

:10012F92 D9440804                fld dword ptr [eax+ecx+04]		

:10012F96 DC2DA0D90110            fsubr qword ptr [1001D9A0]	

x*16384

:10012F9C 8B55EC                  mov edx, dword ptr [ebp-14]		

:10012F9F C1E20E                  shl edx, 0E				

+grid

:10012FA2 035508                  add edx, dword ptr [ebp+08]		

y*512

:10012FA5 8B45E0                  mov eax, dword ptr [ebp-20]

:10012FA8 C1E009                  shl eax, 09		

grid[x][y].y=

:10012FAB D95C0204                fstp dword ptr [edx+eax+04]		


x*16384

:10012FAF 8B45EC                  mov eax, dword ptr [ebp-14]

:10012FB2 C1E00E                  shl eax, 0E			

+grid

:10012FB5 034508                  add eax, dword ptr [ebp+08]		

y*512

:10012FB8 8B4DE0                  mov ecx, dword ptr [ebp-20]

:10012FBB C1E109                  shl ecx, 09				


1-grid[x][y].z		// grid[x][y]+8 bytes

:10012FBE D9440808                fld dword ptr [eax+ecx+08]	

:10012FC2 DC2DA0D90110            fsubr qword ptr [1001D9A0]		

x*16384

:10012FC8 8B55EC                  mov edx, dword ptr [ebp-14]

:10012FCB C1E20E                  shl edx, 0E			

+grid

:10012FCE 035508                  add edx, dword ptr [ebp+08]		

y*512

:10012FD1 8B45E0                  mov eax, dword ptr [ebp-20]

:10012FD4 C1E009                  shl eax, 09		

grid[x][y].z=

:10012FD7 D95C0208                fstp dword ptr [edx+eax+08]


:10012FDB E966FFFFFF              jmp 10012F46

:10012FE0 E945FFFFFF              jmp 10012F2A


It dosnt take rocket science to see that 512 bytes are being allocated for each 16 byte structure
anyone know how to fix it so the elements of the array are stacked togeather without the extra 496 unused bytes in between
:cursing:

#2
dcs

dcs

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 775 posts
*sigh* I wish people would post actual, minimal, complete and compilable snippets rather than skipping stuff that more than half the time contains the issue.

But lemme try to simulate...
#include <stdio.h>


struct TVert

{

   float x,y,z;

   float sel;

};


typedef struct TVert TGrid[32][32];

typedef TGrid *PGrid;


TGrid TheGrid;


int main()

{

   int x;

   int y;

   PGrid Grid = &TheGrid;


   for ( x=0;x<32;x++ )

      for ( y=0;y<32;y++ )

      {

         Grid[x][y]->x=31-Grid[x][y]->x;

         Grid[x][y]->y=31-Grid[x][y]->y;

         Grid[x][y]->z=31-Grid[x][y]->z;

      }

   return 0;

}
When I run this pass the linter, it has much to say:

Quote

main.c 23 error 662: (Warning -- Possible creation of out-of-bounds pointer (31 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 23])
main.c 23 error 662: (Warning -- Possible creation of out-of-bounds pointer (31 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 23])
main.c 23 error 662: (Warning -- Possible creation of out-of-bounds pointer (992 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 21, 23])
main.c 23 error 661: (Warning -- Possible access of out-of-bounds pointer (992 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 21, 23])
main.c 23 error 662: (Warning -- Possible creation of out-of-bounds pointer (31 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 23])
main.c 23 error 662: (Warning -- Possible creation of out-of-bounds pointer (31 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 23])
main.c 23 error 662: (Warning -- Possible creation of out-of-bounds pointer (992 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 21, 23])
main.c 23 error 661: (Warning -- Possible access of out-of-bounds pointer (992 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 21, 23])
main.c 24 error 662: (Warning -- Possible creation of out-of-bounds pointer (31 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 24])
main.c 24 error 662: (Warning -- Possible creation of out-of-bounds pointer (31 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 24])
main.c 24 error 662: (Warning -- Possible creation of out-of-bounds pointer (992 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 21, 24])
main.c 24 error 661: (Warning -- Possible access of out-of-bounds pointer (992 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 21, 24])
main.c 24 error 662: (Warning -- Possible creation of out-of-bounds pointer (31 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 24])
main.c 24 error 662: (Warning -- Possible creation of out-of-bounds pointer (31 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 24])
main.c 24 error 662: (Warning -- Possible creation of out-of-bounds pointer (992 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 21, 24])
main.c 24 error 661: (Warning -- Possible access of out-of-bounds pointer (992 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 21, 24])
main.c 25 error 662: (Warning -- Possible creation of out-of-bounds pointer (31 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 25])
main.c 25 error 662: (Warning -- Possible creation of out-of-bounds pointer (31 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 25])
main.c 25 error 662: (Warning -- Possible creation of out-of-bounds pointer (992 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 21, 25])
main.c 25 error 661: (Warning -- Possible access of out-of-bounds pointer (992 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 21, 25])
main.c 25 error 662: (Warning -- Possible creation of out-of-bounds pointer (31 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 25])
main.c 25 error 662: (Warning -- Possible creation of out-of-bounds pointer (31 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 25])
main.c 25 error 662: (Warning -- Possible creation of out-of-bounds pointer (992 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 21, 25])
main.c 25 error 661: (Warning -- Possible access of out-of-bounds pointer (992 beyond end of data) by operator '[' [Reference: file main.c: lines 18, 20, 21, 25])
main.c 27 error 539: (Warning -- Did not expect positive indentation from line 20)
So I'm thinking it has to do with the declaration of the pointer -- NOT some sort of phantom structure padding. Verify the structure size using the sizeof operator.

#3
alienkinetics

alienkinetics

    Programmer

  • Members
  • PipPipPipPip
  • 154 posts
I wont try to explain why it doesn't work. Just to say, the way you have coded this is going to cause problems with C/C++ regardless.

Therefore, you are always safer to put arrays inside another structure and use pointers to structures.

typedef struct {

   float x,y,z;

   float sel;

} TVert;


typedef struct {

  TVert verts[32][32];

} TGrid;


TGrid TheGrid;


int main()

{

   int x;

   int y;

   TGrid* Grid = &TheGrid;


   for ( x=0;x<32;x++ )

      for ( y=0;y<32;y++ )

      {

         Grid->verts[x][y].x = 31 - Grid->verts[x][y].x;

         Grid->verts[x][y].y = 31 - Grid->verts[x][y].y;

         Grid->verts[x][y].z = 31 - Grid->verts[x][y].z;

      }

   return 0;

}

Buzz PHP Class Library - Web Components Made Easy!
http://www.buzzphp.com/

#4
alienkinetics

alienkinetics

    Programmer

  • Members
  • PipPipPipPip
  • 154 posts
Ok, I'll explain (kinda)

sizeof(TGrid) = 16384
sizeof(Grid[0]) = 16384

Therefore the first index is not an index to the first row, but an index to the entire grid. So, Grid[1] is the grid after the grid you allocated in global memory, and hence your errors.

It has todo with how C/C++ handles arrays which is different to a language such as Pascal.

Just accept that the rule of thumb is to always put arrays inside structures.

It looks clearer to the reader and the code actually works.
Buzz PHP Class Library - Web Components Made Easy!
http://www.buzzphp.com/

#5
Ewe Loon

Ewe Loon

    Learning Programmer

  • Members
  • PipPipPip
  • 49 posts
Thanks, I put the Verts of TGrid into a struct

struct TGrid
{
TVert Verts[32][32];
}
and it works,:w00t:

#6
alienkinetics

alienkinetics

    Programmer

  • Members
  • PipPipPipPip
  • 154 posts
Cool. yea, while Im sure the behaviour of array pointers in C is predictable to a C buff, it isn't always clear from a logical POV.

It was a lesson I learnt some years ago. Always put staic arrays inside structures.

Especially multi dimensional arrays. I know. All the books are bla bla this, and bla bla that.

Rule of thumb peoples
Buzz PHP Class Library - Web Components Made Easy!
http://www.buzzphp.com/

#7
dcs

dcs

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 775 posts
Some tinkering I've been doing seems to show me that, given the original code, the following lines
			Grid[x][y]->x=31-Grid[x][y]->x;

			Grid[x][y]->y=31-Grid[x][y]->y;

			Grid[x][y]->z=31-Grid[x][y]->z;
should be
         (*Grid)[x][y].x = 31 - (*Grid)[x][y].x;

         (*Grid)[x][y].y = 31 - (*Grid)[x][y].y;

         (*Grid)[x][y].z = 31 - (*Grid)[x][y].z;


#8
alienkinetics

alienkinetics

    Programmer

  • Members
  • PipPipPipPip
  • 154 posts
dcs, im sure they should be. And given your post count im sure you are a solid coder.

I just think there has to be a solid, fool proof solution.

I dont like code that when I read I have no idea what the f is going on. Ok. put it this way. The compilier didn't pick up the error. Which is a bad sign.

I beleive students should be provided with decent advice when it comes to these issues.
Buzz PHP Class Library - Web Components Made Easy!
http://www.buzzphp.com/

#9
dcs

dcs

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 775 posts

alienkinetics said:

I dont like code that when I read I have no idea what the f is going on. Ok. put it this way. The compilier didn't pick up the error. Which is a bad sign.

I beleive students should be provided with decent advice when it comes to these issues.
I don't disagree. The first thing I'd ditch is the typedefs, for example, because to me they obfuscate.

With this and another post by the OP, however, I wasn't entirely sure how much of the code was his and what was his to maintain.

Besides, on occasion I do like find answers to such questions as asked.

#10
Ewe Loon

Ewe Loon

    Learning Programmer

  • Members
  • PipPipPip
  • 49 posts
So to Recap for post
All pointer in c++ point to an Array of their Targeted Type, not a single one, this creating an extra dimension For pointers to arrays
So had my code been "Grid[0][x][y]->x=31-Grid[0][x][y]->x;" it would have worked, like wise , if i had defined a "TVert TGridRow[32]" , and defined PGrid like this "TGridRow *PGrid" then "Grid[x][y]->x=31-Grid[x][y]->x;" would have worked

as to the comment about who owns the code, its all mine, but, since its for a dll the function calling conversions , structs and pointers have to be precise, since the application that calls them is already written,

the application is Graphics tool for creating and editing Sculpted prims for Secondlife, I have written the App to be a shell and to get all the creation and modification tools from dll files, making user expansion possible for people who write in different languages,
:)

#11
dcs

dcs

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 775 posts

Ewe Loon said:

So to Recap for post
All pointer in c++ point to an Array of their Targeted Type, not a single one, this creating an extra dimension For pointers to arrays
That's not the way I'd put it. Pointers to arrays are stranger beasts than most.

Ewe Loon said:

So had my code been "Grid[0][x][y]->x=31-Grid[0][x][y]->x;" it would have worked
I get errors; change the arrows to dots.

Ewe Loon said:

as to the comment about who owns the code, its all mine, but, since its for a dll the function calling conversions , structs and pointers have to be precise, since the application that calls them is already written,

the application is Graphics tool for creating and editing Sculpted prims for Secondlife, I have written the App to be a shell and to get all the creation and modification tools from dll files, making user expansion possible for people who write in different languages,
:)
It wasn't so much ownership I was aiming at. Moreso like, "I've got 10k LOC. So I'd rather not make such a vast sweeping change at this point." Or somesuch.

#12
alienkinetics

alienkinetics

    Programmer

  • Members
  • PipPipPipPip
  • 154 posts
Arr. Just put them in structures. Most (if not all) advanced coders will be coding in multiple languages. So its hard to remember how one language interprets a concept vs how another interprets the same.

So, you have to find the common ground. Code in such a way that even a C#, Java, Pascal, etc programmer could understand it.

Otherwise you will never be able to work in a team.

I cant stand code that uses some weird ass pointer logic, which could have been written using simple common language concepts.

There is no speed issue at all. the compilier will produce the same code.
Buzz PHP Class Library - Web Components Made Easy!
http://www.buzzphp.com/