String array size change

i want to create a string array for users and add userDetails there,
(i use linear search to search throught users later)

but if i want to add new user i need to change size of array. what solution u suggest here

int userTotal=100;
String user[userTotal];

void setup(){

user[0]="name,surname"
......1.......99...
user[100]="name,surname"
}

void loop(){
}

void addNewUser(){
user[101]="name,surname";
}

Declare the array large enough to hold the maximum number of users that will ever exist

will that take memory if i declare but they are not filled with any user data

What if it does ? If you go through with your plan to expand the array of Strings, which sound like a bad idea, then at some time you will use up the memory anyway so why not allocate it to start with ?

By the way, expect replies to this topic telling you not to use Strings, but I will leave that to others. Which board are you using ?

esp32

coz i dont know how much i will expand it , it can have 10 users or 100 or 300

so i dont want to declare user[500] and then add 10 users. so each time i search throught it i need to go

for (int i = 0; i <= userTotal; i++) {
   if(user[i].startsWith("xxx")){
    //code 
    break;
  }
}

Expanding the array will increase the memory usage by six bytes per element (on an UNO), may be larger on an ESP32, you can check by printing sizeof(String). The actual memory for the text stored in the String is not part of the array, but is stored on the heap, and will not be allocated until you create the String.

The search should not take all that much time, but if you are concerned about that then keep track of the current number of users and only search for that many.

So you can use a std::vector and take advantage of dynamic allocation, so why bother with a fixed-size C array?

#include <vector>

std::vector<String> users;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);

  for (int i=0; i<10; i++) {
    String  user = "user-";
    user += i + 1;
    users.push_back(user);
  }
  
  // You can use a range based for loop to iterate the vector
  for (String &user : users) {
    Serial.println(user);
  }
}

1 Like

Or std::list which provides better performance for element insertion and deletion at the expense of poorer memory efficiency and lack of random access. The choice depends on your use case.

since insert(append) and update via index number is not so often, and ill use "access using indexing " and linear search over and over again, i think std::vector will be better choice

am i right?

What type of application is the list of users being used in ? It takes an ESP32 about 2 microseconds to iterate through an array of 500 Strings looking for a match. Is your application that time critical ?

nope. but now question is:
is it better to create a String user[500] or create a dynamic string array with std::vector

which one will consume less memory and will be faster and better solution to work on

coz its a time attendance project and whenever someone scan rfid card i will search all users and see if match with any on user[]

so make it 300.

max users can be 500 but most of cases will be below 100 but i never know if it will be 500 :stuck_out_tongue: so i reather create user[500] or use vector

The best solution is the one that works and that you understand

You mention adding users. How will the user data be stored so that it is available after a reset or power cut ?

In the end, with the maximum of 500 users, the memory usage will likely be nearly the same.
The fact is, if you want to allow for up to 500 users, there absolutely has to be sufficient memory for that many, and if you really want to be safe, 500 users who use the maximum length that you are allowing for the data.

IT is always a balance between resource usage (memory, CPU, data transfer, etc.) and global or specific functions efficiency (together with costs, but that's not this case).

Almost any solution reducing the resources can't be always quick, but everything depends on the requirements (e.g. how much is important to get a result in 200ms instead of 50?). So if you want to obtain faster execution you should know it could require more resources/memory (e.g. a fully allocated array), if you want to save resources it can't be as quick as the first one. In any project the costs/benefits balance should always be taken in consideration when designing a system.

Just as an example, if you store the names as a file over SD card, it is the solution with less memory usage, but at the cost of search speed.

Besides, one of my favourite statement when dealing with customer requests is:
"Any IT project can have three properties:
good coding ; made in a short time ; cheap
You can choose only two." :slight_smile:

This is so good. Did u read somewhere or u make it up

I don't know if anyone else did a similar thing, but I kinda fine tuned it during my years of IT work expericence, making the statement as compact as possible to be understandable by the "mean customer" (and here in Italy the customers are used to pay even a lot for hardware but always underestimate software because they "understand" the hardware and don't know a thing about how hard is a good coding...).

But IMHO it's a good and realistic rule of thumb to let customers understand that:

  1. if they want it good and within a short time, can't be cheap
  2. if they want it good and cheap, can't deliver it in a short time
  3. if they want it cheap and in short time, it can't be good

As already noted, each object of the String class is only a few bytes long, the text data itself is stored in dynamically allocated memory as required. Thus Strings will be more memory efficient than c-strings (null-terminated char arrays), especially if there is a large distribution of string lengths.

A std::vector of String objects will be more memory efficient than a static array of String objects if there are significantly fewer allocated Strings than the maximum specified in the array.

Addition and removal (especially) of entries will be easier with std::vector as you'd be using the capabilities of a bulletproof, thoroughly debugged library rather than trying to roll your own implementation.

The time required to traverse the data structure will be indistinguishable between an array and a std::vector (assuming you keep track of the number of active entries in the array implementation).

If it were my project, I'd go with a std::vector of String (or std::string) objects.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.