I would like your help to understand how the below code is producing the prime numbers. The code is correct, but I am not sure how the loop ensures that isprime = trial % primes[3] > 0; is not a prime number.
P.s. I know that 9 is not a prime number, but I would like to understand how the below code understands that 9 is not a prime number... probably it's connected to the sqrt and limit?
// Calculating primes using dynamic memory allocation
#include <iostream>
#include <iomanip>
#include <cmath>                                             // For square root function
int main()
{
  size_t max {};                                             // Number of primes required
  std::cout << "How many primes would you like? ";
  std::cin >> max;                                           // Read number required
  
  if (max == 0) return 0;                                    // Zero primes: do nothing
  
  auto* primes {new unsigned[max]};                          // Allocate memory for max primes
  size_t count {1};                                          // Count of primes found
  primes[0] = 2;                                             // Insert first seed prime
  
  unsigned trial {3};                                        // Initial candidate prime
  
  while (count < max)
  {
    bool isprime {true};                                     // Indicates when a prime is found
    const auto limit = static_cast<unsigned>(std::sqrt(trial));
    for (size_t i {}; primes[i] <= limit && isprime; ++i)
    {
      isprime = trial % primes[i] > 0;                       // False for exact division
    }
    if (isprime)                                             // We got one...
      primes[count++] = trial;                               // ...so save it in primes array
    trial += 2;                                              // Next value for checking
  }
 
 // Output primes 10 to a line 
  
for (size_t i{}; i < max; ++i)
  {
    std::cout << std::setw(10) << primes[i];
    if ((i + 1) % 10 == 0)                                   // After every 10th prime...
      std::cout << std::endl;                                // ...start a new line
  }
  std::cout << std::endl;
  
  delete[] primes;                                           // Free up memory...
  primes = nullptr;                                          // ... and reset the pointer
}
 
    