Compartilhar via


Alinhamento

Os problemas de alinhamento em um aplicativo ODBC geralmente não são diferentes do que em qualquer outro aplicativo. Ou seja, a maioria dos aplicativos ODBC tem poucos ou nenhum problema com o alinhamento. As penalidades por não alinhar endereços variam com o hardware e o sistema operacional e podem ser tão pequenas quanto uma pequena penalidade de desempenho ou tão importante quanto um erro fatal em tempo de execução. Portanto, os aplicativos ODBC e aplicativos ODBC portáteis, em particular, devem ter cuidado para alinhar os dados corretamente.

Um exemplo de quando os aplicativos ODBC encontram problemas de alinhamento é quando alocam um grande bloco de memória e associam diferentes partes dessa memória às colunas em um conjunto de resultados. Isso provavelmente ocorrerá quando um aplicativo genérico deve determinar a forma de um conjunto de resultados em tempo de execução e alocar e associar memória adequadamente.

Por exemplo, suponha que um aplicativo execute uma instrução SELECT inserida pelo usuário e busque os resultados dessa instrução. Como a forma desse conjunto de resultados não é conhecida quando o programa é gravado, o aplicativo deve determinar o tipo de cada coluna depois que o conjunto de resultados é criado e associar memória adequadamente. A maneira mais fácil de fazer isso é alocar um grande bloco de memória e associar endereços diferentes nesse bloco a cada coluna. Para acessar os dados em uma coluna, o aplicativo lança a memória vinculada a essa coluna.

O diagrama a seguir mostra um conjunto de resultados de exemplo e como um bloco de memória pode ser associado a ele usando o tipo de dados C padrão para cada tipo de dados SQL. Cada "X" representa um único byte de memória. (Este exemplo mostra apenas os buffers de dados associados às colunas. Isso é feito para simplificar. No código real, os buffers de comprimento/indicador também devem ser alinhados.)

Associação padrão do tipo de dados C ao tipo de dados SQL

Supondo que os endereços associados sejam armazenados na matriz de endereços , o aplicativo usa as seguintes expressões para acessar a memória associada a cada coluna:

(SQLCHAR *)       Address[0]  
(SQLSMALLINT *)   Address[1]  
(SQLINTEGER *)    Address[2]  

Observe que os endereços associados à segunda e terceira colunas começam em bytes numerados ímpares e que o endereço associado à terceira coluna não é divisível por quatro, que é o tamanho de um SDWORD. Em alguns computadores, isso não será um problema; em outros, isso causará uma pequena penalidade de desempenho; em outros, isso causará um erro fatal em tempo de execução. Uma solução melhor seria alinhar cada endereço associado em seu limite de alinhamento natural. Supondo que isso seja 1 para um UCHAR, 2 para um SWORD e 4 para um SDWORD, isso daria o resultado mostrado na ilustração a seguir, em que um "X" representa um byte de memória que é usado e um "O" representa um byte de memória que não é usado.

Vinculação por limite de alinhamento natural

Embora essa solução não use toda a memória do aplicativo, ela não encontra nenhum problema de alinhamento. Infelizmente, é preciso uma boa quantidade de código para implementar essa solução, pois cada coluna deve ser alinhada individualmente de acordo com seu tipo. Uma solução mais simples é alinhar todas as colunas no tamanho do maior limite de alinhamento, que é 4 no exemplo mostrado na ilustração a seguir.

Vinculação por maior limite de alinhamento

Embora essa solução deixe buracos maiores, o código para implementá-la é relativamente simples e rápido. Na maioria das vezes, isso compensa a penalização paga na memória não utilizada. Para obter um exemplo que usa esse método, consulte Usando SQLBindCol.