Solved

Array size at RunTime

Posted on 2004-08-06
12
386 Views
Last Modified: 2013-11-20
How can I know the size of an array at RunTime.

The array is created with the New operator and storage in a block of memory, but in other procedure wend I receive that blob information I don't kown the size of the array.

Mora than the size I need to know if the array is empty or not.

Thanks.
0
Comment
Question by:DAE
  • 6
  • 6
12 Comments
 

Author Comment

by:DAE
ID: 11739929
Here is a piece of the code, I hope you understand. :)

void CCalendarCtrl::SetWeekDaysArrayBlobData(CPropExchange* pPX)
{
      if(!pPX->IsLoading()){ // STORAGE PART
            long items = WeekDaysCustomThemeArray.GetSize();

            O_OFFSETWEEKDAY StorageArray;
            StorageArray.offset = new O_BLOBARRAYWEEKDAYS[items];

            hWeekDaysArrayOffset = GlobalAlloc(GMEM_FIXED, sizeof(StorageArray));
            
            if(hWeekDaysArrayOffset != NULL){
                  O_OFFSETWEEKDAY *p_mem = (O_OFFSETWEEKDAY*)GlobalLock(hWeekDaysArrayOffset);
                  if(p_mem != NULL){
                        p_mem->size = sizeof(StorageArray);
                        p_mem->offset = new O_BLOBARRAYWEEKDAYS[items];
                        for (long i = 0; i < items; i++){
                              p_mem->offset[i].items = items;
                              p_mem->offset[i].themeoptions = WeekDaysCustomThemeArray[i];
                        }

                        PX_Blob(pPX, _T("WeekDaysArrayStorage"), hWeekDaysArrayOffset);
                        GlobalUnlock(hWeekDaysArrayOffset);
                  }else{
                        HGLOBAL hTmp = NULL;
                        PX_Blob(pPX, _T("WeekDaysArrayStorage"), hTmp);
                  }
                  GlobalFree(hWeekDaysArrayOffset);
                  hWeekDaysArrayOffset = NULL;
            }else{
                  PX_Blob(pPX, _T("WeekDaysArrayStorage"), hWeekDaysArrayOffset);
            }
      }else{ // LOAD PART
            PX_Blob(pPX, _T("WeekDaysArrayStorage"), hWeekDaysArrayOffset);
            if(hWeekDaysArrayOffset != NULL){
                  O_OFFSETWEEKDAY * p_mem = (O_OFFSETWEEKDAY*)GlobalLock(hWeekDaysArrayOffset);
                  if(p_mem != NULL){
                        if(p_mem->offset > 0){ // *** HERE IS WHERE I NEED TO KNOW IF THE ARRAY IS EMPTY OR NOT
                              if(p_mem->offset[0].items != 0){
                                    for (long i = 0; i < p_mem->offset[0].items; i++){
                                          SetWeekDaysColorTheme(p_mem->offset[0].themeoptions.index, eBackColor, p_mem->offset[0].themeoptions.theme.thBackColor);
                                    }
                              }
                        }
                        GlobalUnlock(hWeekDaysArrayOffset);
                  }
                  GlobalFree(hWeekDaysArrayOffset);
                  hWeekDaysArrayOffset = NULL;
            }
      }
}
0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 11739933
You can't know, you have to pass array size too.
0
 

Author Comment

by:DAE
ID: 11740020
Yes, I think in that, but I have to do it with this structure and I can't modified this (thanks to Microsoft)

typedef struct tagO_OFFSETWEEKDAY {
      long size; // Size of the block of memory.
      O_BLOBARRAYWEEKDAYS* offset; // Pointer to the dynamic created array.
} O_OFFSETWEEKDAY;

I think in a not elegant solution that is have an item of the array with the size of the array, but if the array is empty I have my problem.
0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 11740111
O_OFFSETWEEKDAY is not an array, too much structures in WinAPI have this form (size as first element), and I think is very practical.
offset can point to NULL or to a valid buffer, even if array size is zero.
0
 

Author Comment

by:DAE
ID: 11740495
Jaime you speak in spanish???

You don´t understand me and my english is very poor to explain the complexity of the problem.

If you don't speak spanish I give you the point and I try to solve the problem myself.
0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 11740516
Bueno, explicalo en español y despues lo traducimos a ingles, porque son las reglas de EE
(Well, explain it in spanish and after that we translate it to english, because them are the rules at EE)
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 

Author Comment

by:DAE
ID: 11740750
El problema es el siguiente:

Estoy desarrollando un componente ActiveX y tengo que guardar un Array dinámico en lo que se llama "La Persistencia" del ActiveX (las propiedades que se guardan dentro del exe cuando se compila).

El sistema que se utiliza para guardar estos datos en la "persistencia" es reservar un bloque de memoria sin fragmentar donde se guarda la información que se desea almacenar.

Microsoft pide que la estructura para ser guardada en la persistencia del ActiveX tenga la siguiente forma:

typedef struct {
     long size; // Tamaño del block de memoria que se va a guardar. (que es el tamaño de la estructura de abajo)
     estructura_definida offset; // Estructura que se va a guardar.
} estructura;

En mi caso la "estructura_definida" (que se llama offset en el ejemplo) es un puntero a un Array que creo dinámicamente, entonces queda asi:

typedef struct {
     long size;
     estructura_definida* offset;
} estructura;

Esta "estructura_definida" es de la que hago el array dinámico y tiene este formato:

typedef struct {
      long items; // Guardo la cantidad de items que tiene el Array
      otra_estructura themeoptions; // Estructura definida por mi, que no viene al caso.
} estructura_definida;

Entonces en el código lo que hago es lo siguiente:

estructura Dummy;
Dummy.offset = new estructura_definida[items];

Ahora bien, el valor de "items" solo lo se cuando estoy guardando la estructura en la memoria, pero no la conozco cuendo recupero la memoria y la trasformo a la estructura "estructura_definida"

Esto acarrea el problema de que el array se encuentre vacio y que la variable "items" nisiquiera exista, por ende, no poder tratar a esta estructura como corresponde (vacia).

Creo que una solución seria que el array nunca este vacio, sino que al menos tenga un elemento con la variable "items" igual a 0.

--------

Mi segundo problema es que al crear un Array dinámico este se guarda en lo que se llama el "heap" de la memoria, por ende no estoy cumpliendo de que la estructura a guardar sea un bloque de memoria sin fragmentar. Sino que lo que tengo sin fragmentar es la variable "items" y la referencia a memoria del primer item del array dinámico que se encuentra en otro pedazo de la memoria.

¿Existe alguna forma de reservar un bloque de memoria y guardar nuevamente la estructura que posee el array dinámico en un bloque sin fragmentar de memoria?
0
 
LVL 55

Accepted Solution

by:
Jaime Olivares earned 50 total points
ID: 11741186
You can make something like this:

   long bagsize = sizeof(otra_estructura)*items + 4];  
   BYTE *bag = new BYTE[bagsize];   <--- Notice +4
   *((long*)bag) = bagsize;
   memcpy(bag+4, pointertoyourdata, bagsize-4);  // otra_estructura

    now bag have all you need to pass to your control. To recover from control, extract data in a buffer similar to bag, and create a pointer to bag+4.

otra_estructura *yourdata = (otra_estructura *)(bag+4)

   
0
 

Author Comment

by:DAE
ID: 11744114
Thanks Jaime. I'm going to try this.
0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 11744140
La idea es que tu estabas pasando una estructura que solo contenia el tamaño y un puntero. En mi implementacion estas pasando el arreglo mismo, precedido de el tamaño.
0
 

Author Comment

by:DAE
ID: 11744593
Why "+4" ???
0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 11744613
You have to pass all data required by control. all data means: the size and the data itself, so I reserve enough space for the size var and the data itself, and size var is 4 bytes long (32 bits).

0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Login Script to Copy Folders 12 21
Question regarding Copy/Paste 16 86
iSeries FTP Exit Program 8 114
substring method in java 1 79
Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now