C language > Tips & tricks
Dynamic array of structures or pointers
frankie:
In many applications we would like to have same functionalities of C++ vectors with all their rich set of methods to handle dynamic arrays of data structures or pointers.
It would be very nice to have possibility to add, remove and insert items at random positions, expand and squeeze your array as needed ::)
If you don't want to spend time to write your personal library for that you can use the DPA (Dynamic Pointers Array) and DSA (Dynamic Structure Array) already coded and, presumably >:(, tested for you in the ComCtl32.dll library.
Below an example of the possibilities:
--- Code: ---#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
HDSA hDsa = DSA_Create(sizeof(char[32]), 2);
printf("------ Writing the array ------\n");
for (int i=0; i<20; i++)
{
char str[32];
sprintf(str, "Test%2d", i+1);
printf (" - Appending string \"%s\".\n", str);
//DSA_GetSize present in COMCTL32.DLL V.6.00.00
//printf (" - Appending string \"%s\". Actual array size = %llu\n", str, DSA_GetSize(hDsa));
DSA_AppendItem(hDsa, str);
}
printf("------ Reading the array ------\n");
int cItems = DSA_GetItemCount(hDsa);
for (int i=0; i<cItems; i++)
{
char str[32];
DSA_GetItem(hDsa, i, str);
printf (" - Read string \"%s\".\n", str);
}
printf("------ Invert the array ------\n");
//DSA_Sort(hDsa, fn_compare, 0); //DSA_Sort present in COMCTL32.DLL V.6.00.00
cItems = DSA_GetItemCount(hDsa);
for (int i=0; i<cItems/2; i++)
{
char str[32];
memcpy(str, DSA_GetItemPtr(hDsa, i), sizeof(str));
memcpy(DSA_GetItemPtr(hDsa, i), DSA_GetItemPtr(hDsa, cItems - i - 1), sizeof(str));
memcpy(DSA_GetItemPtr(hDsa, cItems - i - 1), str, sizeof(str));
}
printf("------ Reading the array ------\n");
cItems = DSA_GetItemCount(hDsa);
for (int i=0; i<cItems; i++)
{
char *str = DSA_GetItemPtr(hDsa, i);
printf (" - Read string \"%s\".\n", str);
}
printf("------ Invert again the array ------\n");
cItems = DSA_GetItemCount(hDsa);
for (int i=0; i<cItems/2; i++)
{
char str[32];
memcpy(str, DSA_GetItemPtr(hDsa, i), sizeof(str));
memcpy(DSA_GetItemPtr(hDsa, i), DSA_GetItemPtr(hDsa, cItems - i - 1), sizeof(str));
memcpy(DSA_GetItemPtr(hDsa, cItems - i - 1), str, sizeof(str));
}
printf("------ Remove odd items from the array ------\n");
cItems = DSA_GetItemCount(hDsa);
for (int i=0; i<cItems/2; i++)
DSA_DeleteItem(hDsa, i);
printf("------ Reading the array ------\n");
cItems = DSA_GetItemCount(hDsa);
for (int i=0; i<cItems; i++)
{
char *str = DSA_GetItemPtr(hDsa, i);
printf (" - Read string \"%s\".\n", str);
}
printf("------ Add odd items after even items in the array ------\n");
cItems = DSA_GetItemCount(hDsa);
for (int i=0; i<cItems*2; i+=2)
{
char str[32];
sprintf(str, "Test%2d", i+1);
printf (" - Adding string \"%s\".\n", str);
DSA_InsertItem(hDsa, i+1, str);
}
printf("------ Reading the array ------\n");
cItems = DSA_GetItemCount(hDsa);
for (int i=0; i<cItems; i++)
{
char *str = DSA_GetItemPtr(hDsa, i);
printf (" - Read string \"%s\".\n", str);
}
printf("------ Reading directly the array ------\n");
cItems = DSA_GetItemCount(hDsa);
char (*first)[32] = DSA_GetItemPtr(hDsa, 0);
for (int i=0; i<cItems; i++)
{
printf (" - Read string \"%s\".\n", first[i]);
}
printf("------ Destroy the array ------\n");
DSA_Destroy(hDsa);
return 0;
}
--- End code ---
EDIT: I forget to say that the array can be accessed as a standard array using the pointer to the first element as array address. See last part of the example above updated with the feature.
jj2007:
Hi Frankie,
That's a nice one, thanks :)
I checked with Masm32 and found out that the declarations are all there, but we never used DSA_*, except for one post by Donkey 12 years ago. Astonishing 8)
TimoVJL:
Nice :)
This usually helps these examples
--- Code: ---#define WIN32_LEAN_AND_MEAN
...
#pragma comment(lib, "comctl32.lib")
...
--- End code ---
Vortex:
Hi Frankie,
Thanks. Here is my report of Windows 7 SP1 64-bit, the list of exported functions with the leading symbol DSA_ :
--- Code: ---E:\PellesC\Bin>podump.exe /EXPORTS C:\Windows\System32\comctl32.dll | findstr "DSA_"
140 1E 000007FF75870770 DSA_Create
147 1F 000007FF75870B58 DSA_DeleteAllItems
146 20 000007FF75870AA0 DSA_DeleteItem
141 21 000007FF758707B8 DSA_Destroy
184 22 000007FF75870878 DSA_DestroyCallback
183 23 000007FF7587080C DSA_EnumCallback
142 24 000007FF7587089C DSA_GetItem
143 25 000007FF758708D8 DSA_GetItemPtr
144 26 000007FF758709C8 DSA_InsertItem
145 27 000007FF758708F4 DSA_SetItem
--- End code ---
jj2007:
There should be some more, e.g. DSA_Sort
--- Code: ---DSA_AppendItem macro
DSA_Clone function
DSA_Create function
DSA_DeleteAllItems function
DSA_DeleteItem function
DSA_Destroy function
DSA_DestroyCallback function
DSA_EnumCallback function
DSA_GetItem function
DSA_GetItemCount macro
DSA_GetItemPtr function
DSA_GetSize function
DSA_InsertItem function
DSA_SetItem function
DSA_Sort function
--- End code ---
Navigation
[0] Message Index
[#] Next page
Go to full version