Partager via


qsort_s

effectue un tri rapide.Une version de qsort avec des améliorations de sécurité comme décrit dans Fonctionnalités de sécurité du CRT.

void qsort_s(
   void *base,
   size_t num,
   size_t width,
   int (__cdecl *compare )(void *, const void *, const void *),
   void * context
);

Paramètres

  • base
    Début de tableau cible.

  • num
    taille du tableau dans les éléments.

  • width
    taille d'élément en octets.

  • compare
    fonction de comparaison.le premier argument est le pointeur d' context .Le deuxième argument est un pointeur vers key pour la recherche.Le troisième argument est un pointeur vers l'élément de tableau à comparer à key.

  • context
    Un pointeur vers un contexte, qui peut être n'importe quel objet auquel la routine d' compare doit accéder.

Notes

La fonction d' qsort_s implémente un algorithme de rapide-tri pour trier un tableau d'éléments d' num , chacun d'octets d' width .L'argument base est un pointeur vers la base du tableau à trier.qsort_s remplace ce tableau dans lequel les éléments sont triés.L'argument compare est un pointeur vers une routine fournie par l'utilisateur qui compare deux éléments de tableau et retourne une valeur spécifiant leur relation.qsort_s appelle la routine d' compare une ou plusieurs fois pendant le tri, en passant des pointeurs vers deux éléments de tableau à chaque appel :

compare( context, (void *) & elem1, (void *) & elem2 );

La routine doit comparer les éléments puis retourner l'une des valeurs suivantes :

Valeur de retour

Description

< 0

elem1 moins qu' elem2

0

elem1 équivalent à elem2

> 0

elem1 supérieur elem2

Le tableau est triée en augmentant la commande, comme défini par la fonction de comparaison.Pour trier une classe par ordre décroissant, inverser le sens de « supérieur à » et « inférieur à » dans la fonction de comparaison.

Si des paramètres incorrects sont passés à la fonction, le gestionnaire de paramètre non valide est appelé, comme décrit dans Validation des paramètres.Si est autorisé à l'exécution de se poursuivre, la fonction retourne et errno est défini à EINVAL.Pour plus d'informations, consultez errno, _doserrno, _sys_errlist, et _sys_nerr.

conditions d'erreur

clé

base

compare

num

largeur

errno

NULL

quels

quels

quels

quels

EINVAL

quels

NULL

quels

!= 0

quels

EINVAL

quels

quels

quels

quels

<= 0

EINVAL

quels

quels

NULL

quels

quels

EINVAL

qsort_sa le même comportement que qsort mais a le paramètre d' context et définit errno.En passant un paramètre d' context , les fonctions de comparaison peuvent utiliser un pointeur d'objet pour accéder aux fonctionnalités d'objet ou à d'autres informations non accessibles par l'intermédiaire d'un pointeur d'élément.L'ajout du paramètre d' context rend qsort_splus sécurisées car context peut être utilisé pour éviter les bogues de réentrance présentés à l'aide de variables statiques pour rendre les informations partagées à la fonction d' compare .

Configuration requise

routine

en-tête requis

qsort_s

<stdlib.h> et <search.h>

Pour des informations de compatibilité supplémentaires, consultez Compatibilité dans l'introduction.

bibliothèques : toutes les versions de Fonctionnalités de bibliothèque CRT.

Exemple

l'exemple suivant montre comment utiliser le paramètre d' context dans la fonction d' qsort_s.Le paramètre d' context facilite pour effectuer des tris thread-safe.Au lieu d'utiliser les variables statiques qui doivent être synchronisées pour garantir la sécurité des threads, passez un paramètre différent d' context dans chaque type.dans cet exemple, un objet de paramètres régionaux est utilisé comme paramètre d' context .

// crt_qsort_s.cpp
// compile with: /EHsc /MT
#include <stdlib.h>
#include <stdio.h>
#include <search.h>
#include <process.h>
#include <locale.h>
#include <locale>
#include <windows.h>
using namespace std;

// The sort order is dependent on the code page.  Use 'chcp' at the
// command line to change the codepage.  When executing this application,
// the command prompt codepage must match the codepage used here:

#define CODEPAGE_850

#ifdef CODEPAGE_850
// Codepage 850 is the OEM codepage used by the command line,
// so \x00e1 is the German Sharp S in that codepage and \x00a4
// is the n tilde.

char *array1[] = { "wei\x00e1", "weis", "annehmen", "weizen", "Zeit",
                   "weit" };
char *array2[] = { "Espa\x00a4ol", "Espa\x00a4" "a", "espantado" };
char *array3[] = { "table", "tableux", "tablet" };

#define GERMAN_LOCALE "German_Germany.850"
#define SPANISH_LOCALE "Spanish_Spain.850"
#define ENGLISH_LOCALE "English_US.850"

#endif

#ifdef CODEPAGE_1252
   // If using codepage 1252 (ISO 8859-1, Latin-1), use \x00df
   // for the German Sharp S and \x001f for the n tilde.
char *array1[] = { "wei\x00df", "weis", "annehmen", "weizen", "Zeit",
                   "weit" };
char *array2[] = { "Espa\x00f1ol", "Espa\x00f1" "a", "espantado" };
char *array3[] = { "table", "tableux", "tablet" };

#define GERMAN_LOCALE "German_Germany.1252"
#define SPANISH_LOCALE "Spanish_Spain.1252"
#define ENGLISH_LOCALE "English_US.1252"

#endif

// The context parameter lets you create a more generic compare.
// Without this parameter, you would have stored the locale in a
// static variable, thus making sort_array vulnerable to thread
// conflicts.

int compare( void *pvlocale, const void *str1, const void *str2)
{
    char s1[256];
    char s2[256];
    strcpy_s(s1, 256, *(char**)str1);
    strcpy_s(s2, 256, *(char**)str2);
    _strlwr_s( s1, sizeof(s1) );
    _strlwr_s( s2, sizeof(s2) );

    locale& loc = *( reinterpret_cast< locale * > ( pvlocale));

    return use_facet< collate<char> >(loc).compare(s1, 
       &s1[strlen(s1)], s2, &s2[strlen(s2)]);

}

void sort_array(char *array[], int num, locale &loc)
{
    qsort_s(array, num, sizeof(char*), compare, &loc);
}

void print_array(char *a[], int c)
{
   for (int i = 0; i < c; i++)
     printf("%s ", a[i]);
   printf("\n");
       
}

void sort_german(void * Dummy)
{
   sort_array(array1, 6, locale(GERMAN_LOCALE));
}

void sort_spanish(void * Dummy)
{   
   sort_array(array2, 3, locale(SPANISH_LOCALE));     
}

void sort_english(void * Dummy)
{   
   sort_array(array3, 3, locale(ENGLISH_LOCALE));   
}

int main( )
{

   int i;
   HANDLE threads[3];
   
   printf("Unsorted input:\n");
   print_array(array1, 6);
   print_array(array2, 3);
   print_array(array3, 3);


   // Create several threads that perform sorts in different
   // languages at the same time. 

   threads[0] = reinterpret_cast<HANDLE>(
                 _beginthread( sort_german , 0, NULL));
   threads[1] = reinterpret_cast<HANDLE>(
                 _beginthread( sort_spanish, 0, NULL));
   threads[2] = reinterpret_cast<HANDLE>(
                 _beginthread( sort_english, 0, NULL));

   for (i = 0; i < 3; i++)
   {
      if (threads[i] == reinterpret_cast<HANDLE>(-1))
      {
         printf("Error creating threads.\n");
         exit(1);
      }
   }

   // Wait until all threads have terminated.
   WaitForMultipleObjects(3, threads, true, INFINITE);
  
   printf("Sorted output: \n");

   print_array(array1, 6);
   print_array(array2, 3);
   print_array(array3, 3);

  
  
}

Résultat de l'exemple

Unsorted input:
weiß weis annehmen weizen Zeit weit 
Español España espantado 
table tableux tablet 
Sorted output: 
annehmen weiß weis weit weizen Zeit 
España Español espantado 
table tablet tableux

Équivalent .NET Framework

Sort

Voir aussi

Référence

Rechercher et trier

bsearch_s

_lsearch_s

qsort