Partilhar via


Alinhamento

Os problemas de alinhamento numa aplicação ODBC geralmente não são diferentes dos que acontecem em qualquer outra aplicação. Ou seja, a maioria das aplicações ODBC tem poucos ou nenhuns problemas de alinhamento. As penalizações por não alinhar endereços variam consoante o hardware e o sistema operativo e podem ser tão pequenas como uma ligeira penalização de desempenho ou tão graves como um erro fatal em tempo de execução. Por isso, as aplicações ODBC, e as aplicações ODBC portáteis em particular, devem ter cuidado para alinhar os dados corretamente.

Um exemplo de quando aplicações ODBC enfrentam problemas de alinhamento é quando alocam um grande bloco de memória e associam diferentes partes dessa memória às colunas de um conjunto de resultados. Isto é mais provável quando uma aplicação genérica tem de determinar a forma de um conjunto de resultados em tempo de execução e alocar e vincular a memória em conformidade.

Por exemplo, suponha que uma aplicação executa uma instrução SELECT introduzida pelo utilizador e obtém os resultados dessa instrução. Como a forma deste conjunto de resultados não é conhecida quando o programa é escrito, a aplicação deve determinar o tipo de cada coluna após a criação do conjunto de resultados e associar a memória em conformidade. A forma mais fácil de o fazer é alocar um bloco grande de memória e associar diferentes endereços nesse bloco a cada coluna. Para aceder aos dados numa coluna, a aplicação projeta a memória associada a essa coluna.

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

Associar por padrão o tipo de dados C ao tipo de dados SQL

Assumindo que os endereços vinculados estão armazenados no array de Endereços , a aplicação utiliza as seguintes expressões para aceder à memória vinculada a cada coluna:

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

Note que os endereços atribuídos à segunda e terceira colunas começam em bytes ímpares e que o endereço atribuído à terceira coluna não é divisível por quatro, que é o tamanho de uma SDWORD. Em algumas máquinas, isto não será um problema; noutros, causará uma ligeira penalização de desempenho; noutros ainda, pode causar um erro fatal em tempo de execução. Uma solução melhor seria alinhar cada endereço limite na sua fronteira natural de alinhamento. Assumindo que isto é 1 para um UCHAR, 2 para um SWORD e 4 para um SDWORD, isto daria o resultado mostrado na ilustração seguinte, onde um "X" representa um byte de memória usado e um "O" representa um byte de memória não utilizado.

Ligação por fronteira de alinhamento natural

Embora esta solução não utilize toda a memória da aplicação, não encontra quaisquer problemas de alinhamento. Infelizmente, é necessário uma quantidade considerável de código para implementar esta solução, pois cada coluna tem de ser alinhada individualmente de acordo com o seu tipo. Uma solução mais simples é alinhar todas as colunas no tamanho da maior fronteira de alinhamento, que é 4 no exemplo mostrado na ilustração seguinte.

Vinculação pelo maior limite de alinhamento

Embora esta solução deixe lacunas maiores, o código para a implementar é relativamente simples e rápido. Na maioria dos casos, isto compensa a penalização paga em memória não utilizada. Para um exemplo que utiliza este método, veja Using SQLBindCol.