error accessing large extern array

Hi
Sorry about my poor English.

I am trying to build an Arabic font library for Nokia 5110 LCD.
I start by #include <PCD8544.h>, and successfully show some bitmaps on LCD.
I move next to make glyphs processing logic.

In font.h, i write:

#ifdef __cplusplus
extern "C" {
#endif

#define byte	unsigned char

#define	NOT_JOINED	0x00
#define	PRV_JOINED	0x01
#define	NXT_JOINED	0x02

typedef struct ArabicGlyphsTable {
	int		utf32Code;
	byte		widths[4];
	byte		flags;//NOT_JOINED,PRV_JOINED,NXT_JOINED
	byte		*isolatedBitmap;
	byte		*prvJoinedBitmap;
	byte		*nxtJoinedBitmap;
	byte		*bthJoinedBitmap;
}ARABICGLYPHSTABLE;
extern ARABICGLYPHSTABLE font8_arabicglyphstable[];

byte *getArabicGlyph(int utf32code,bool bPrvJoined,bool bNxtJoined,byte *pwidth);

#ifdef __cplusplus
}
#endif

and in font.c (40K bytes file), i write:

#include "font.h"

byte font8_Iso_C8_Bitmap[] = {
	//........
	//........
	//........
	//........
	//........
	//........
	//........
	//........
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	//.#....##
	//.#.....#
	//.#######
	//........
	//........
	//....##..
	//........
	//........
	0x00,0x07,0x04,0x04,0x24,0x24,0x05,0x07
};
byte font8_Nxt_C8_Bitmap[] = {
	//....
	//....
	//....
	//....
	//....
	//....
	//....
	//..#.
	0x00,0x00,0x80,0x00,
	//..##
	//...#
	//####
	//....
	//....
	//###.
	//....
	//....
	0x24,0x24,0x25,0x07
};
byte font8_Prv_C8_Bitmap[] = {
	//.......
	//.......
	//.......
	//.......
	//.......
	//.......
	//.......
	//.......
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	//#....##
	//#.....#
	//#######
	//.......
	//.......
	//....##.
	//.......
	//.......
	0x07,0x04,0x04,0x04,0x24,0x25,0x07
};
byte font8_Bth_C8_Bitmap[] = {
	//....
	//....
	//....
	//....
	//....
	//....
	//....
	//..#.
	0x00,0x00,0x80,0x00,
	//..##
	//...#
	//####
	//....
	//....
	//.##.
	//....
	//....
	0x04,0x24,0x25,0x07
};

//same as above for other 32 characters

ARABICGLYPHSTABLE font8_arabicglyphstable[] = {
	{0x0628,[8,7,4,4],NEXT_JOINED|PREVIOUS_JOINED,font8_Iso_C8_Bitmap,font8_Prv_C8_Bitmap,font8_Nxt_C8_Bitmap,font8_Bth_C8_Bitmap},
	...
	//next 32 entries for each character
};

byte *getArabicGlyph(int utf32code,bool bPrvJoined,bool bNxtJoined,byte *pwidth)
{
  int items = sizeof(font8_arabicglyphstable)/sizeof(font8_arabicglyphstable[0]);
 
  for (int i = 0; i < items; i++)
  {
    if(utf32code == font8_arabicglyphstable[i].utf32Code)//<-- this line freez program/serial monitor execution
    {
        if(bPrvJoined && bNxtJoined)
	{
	  *pwidth = font8_arabicglyphstable[i].widths[3];
          return font8_arabicglyphstable[i].bothJoinedBitmap;
	}
        else if(bPrvJoined)
	{
	  *pwidth = font8_arabicglyphstable[i].widths[1];
          return font8_arabicglyphstable[i].previousJoinedBitmap;
	}
        else if(bNxtJoined)
	{
	  *pwidth = font8_arabicglyphstable[i].widths[2];
          return font8_arabicglyphstable[i].nextJoinedBitmap;
	}
        else 
	{
	  *pwidth = font8_arabicglyphstable[i].widths[0];
          return font8_arabicglyphstable[i].isolatedBitmap;
	}
    }
    
  }

  *pwidth = 0;
  return NULL;
}

The indicated line stops program execution and freezes serial monitor output.
To check for out-of-boundary index error,I commented out “for(…)” statement, and the program works well for all array indexes (0 to 32).

byte *getArabicGlyph(int utf32code,bool bPrvJoined,bool bNxtJoined,byte ,byte *pwidth)
{
  int items = sizeof(font8_arabicglyphstable)/sizeof(font8_arabicglyphstable[0]);
 
  //for (int i = 0; i < items; i++)
  //{
    if(utf32code == font8_arabicglyphstable[0].utf32Code)//hard coded index, from 0 to 32 works well
    {
        if(bPrvJoined && bNxtJoined)
	{
	  *pwidth = font8_arabicglyphstable[0].widths[3];
          return font8_arabicglyphstable[0].bothJoinedBitmap;
	}
        else if(bPrvJoined)
	{
	  *pwidth = font8_arabicglyphstable[0].widths[1];
          return font8_arabicglyphstable[0].previousJoinedBitmap;
	}
        else if(bNxtJoined)
	{
	  *pwidth = font8_arabicglyphstable[0].widths[2];
          return font8_arabicglyphstable[0].nextJoinedBitmap;
	}
        else 
	{
	  *pwidth = font8_arabicglyphstable[0].widths[0];
          return font8_arabicglyphstable[0].isolatedBitmap;
	}
    }
    
  //}

  *pwidth = 0;
  return NULL;
}

i cannot find the problem.
i appreciate your help.

What arduino do you have to deal with a possibly huge array? What’s the size of your array? (On a uno the GCC compiler fixes Max array size at 32k which is plenty when you really have only 2k of SRAM)

my board is arduino nano

And how many bytes in your arrays? (only 28 glyphs?)

sizeof(font8_arabicglyphstable) = 612

hali9988:
sizeof(font8_arabicglyphstable) = 612

sure if you look at your struct

typedef struct ArabicGlyphsTable {
	int		utf32Code;
	byte		widths[4];
	byte		flags;//NOT_JOINED,PRV_JOINED,NXT_JOINED
	byte		*isolatedBitmap;
	byte		*prvJoinedBitmap;
	byte		*nxtJoinedBitmap;
	byte		*bthJoinedBitmap;
}ARABICGLYPHSTABLE;

it’s full of bitmap pointers. how much TOTAL data is needed?

How much memory does the compiler tell you is being used? It doesn't appear that the font table and font8_arabicglyphstable array would fit within the dynamic memory of a nano, or if it does there can't be much memory left for other uses. The common practice for large arrays whose contents never change is to store them in the program storage space (flash memory).

Testing the code by hard coding one array element of the font8_arabicglyphstable array can be deceptive, the compiler is very good at optimizing the code, and when it sees you are only using a single element of an array, it will often eliminate the array completely and just hard-code the contents of that particular array element into the code instead.

bitmap data = 1524 bytes

PLATFORM: Atmel AVR 1.15.0 > Arduino Nano ATmega328
HARDWARE: ATMEGA328P 16MHz, 2KB RAM, 30KB Flash
PACKAGES: toolchain-atmelavr 1.50400.190710 (5.4.0), framework-arduinoavr 4.1.2
LDF: Library Dependency Finder → http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 7 compatible libraries
Scanning dependencies…
Dependency Graph
|-- 1.4.4
|-- 1.0
Checking size .pio\build\nanoatmega328\firmware.elf
Memory Usage → http://bit.ly/pio-memory-usage
DATA: [==========] 120.0% (used 2457 bytes from 2048 bytes)
PROGRAM: [=== ] 30.4% (used 9352 bytes from 30720 bytes)

...(used 2457 bytes from 2048 bytes)
did this mean i overflow my data segment?

Yes it means that even before you start using any dynamic memory you have already exceeded all the SRAM available in your Arduino

Need to get something a bit more capable (esp32 for example if you want to keep a small form factor) or see if you can use the flash through PROGMEM and only bring in the data you need in RAM when needed

Testing the code by hard coding one array element of the font8_arabicglyphstable array can be deceptive, the compiler is very good at optimizing the code

very goooood

this is my first post.
it was great eperience.

i appreciate your help.
thank you.