Pergunta

Existe alguma sobrecarga de utilização de matrizes de comprimento variável? Poderia o tamanho do conjunto ser passados ??via linha de comando argumento em tempo de execução? Por que é introduzido, em comparação com automático e alocar dinamicamente uma matriz?

Foi útil?

Solução

VLA tem alguma sobrecarga (em comparação com "normal" com o nome de compilação em tempo de tamanho array).

comprimento de tempo de execução Em primeiro lugar, tem no entanto a língua lhe fornece meios para obter o tamanho real da matriz em tempo de execução (usando sizeof). Isto significa imediatamente que o tamanho real da matriz tem de ser armazenado em algum lugar. Isso resulta em alguma sobrecarga de memória-array por insignificante. No entanto, desde VLAs só pode ser declarada como objetos automáticas, esta sobrecarga de memória não é algo que ninguém jamais iria aviso prévio. É como declarar uma variável local extra de tipo integral.

Em segundo lugar, VLA é normalmente alocados na pilha, mas por causa de seu tamanho variável, caso em geral a sua localização exacta na memória não é conhecido em tempo de compilação. Por esta razão, a implementação subjacente geralmente tem que implementá-lo como um ponteiro para um bloco de memória. Isto introduz uma sobrecarga de memória adicional (para o ponteiro), que é mais uma vez completamente insignificante pelas razões descritas acima. Este também apresenta ligeira sobrecarga de desempenho, uma vez que temos de ler o valor do ponteiro, a fim de encontrar a matriz real. Esta é a mesma sobrecarga você recebe ao acessar matrizes ed-malloc (e não ficar com as matrizes de tamanho em tempo de compilação com nomes).

Uma vez que o tamanho da VLA é um valor inteiro de tempo de execução, ele pode, naturalmente, ser passado como um argumento de linha de comando. O VLA não importa onde seu tamanho vem.

VLA foram introduzidos como matrizes de run-sized de tempo com baixo custo de alocação / desalocação. Eles se encaixam entre matrizes de compilação de tamanho em tempo chamados "normais" (que têm praticamente zero custo de alocação-deallocation, mas o tamanho fixo) e matrizes ed-malloc (tamanho em tempo de execução, que têm, mas o custo relativamente alto alocação-deallocation).

VLA obedecer [quase] as mesmas regras da vida dependente do escopo como automáticas (ou seja local) objetos, o que significa que, no caso geral, eles não podem substituir matrizes malloc-ed. Eles aplicabilidade está limitada a situações em que você precisa de uma rápida matriz de tamanho em tempo de execução com uma vida automática típica.

Outras dicas

Há alguma sobrecarga de tempo de execução com matrizes de comprimento variável, mas você teria que estar trabalhando bastante difícil de medir. Note-se que sizeof(vla) não é uma constante de tempo de compilação se vla é uma matriz de comprimento variável.

O tamanho da matriz pode ser passado para uma função em tempo de execução. Se você optar por ter o tamanho de um argumento de linha de comando e convertê-lo em um inteiro e passar isso para a função em tempo de execução, que assim seja -. Ele vai trabalhar

matrizes de comprimento variável são usados ??porque as variáveis ??são automaticamente alocados para o tamanho correto e liberado automaticamente na saída da função. Isso evita o excesso de alocação de espaço (alocando espaço suficiente para o tamanho máximo possível quando você trabalhar principalmente com os tamanhos mínimos), e evita problemas com a memória limpeza.

Além disso, com arrays multidimensionais, AFAIK ele se comporta mais como Fortran - você pode configurar dinamicamente todas as dimensões, em vez de ser preso com tamanhos fixos para todos, mas a dimensão principal da matriz.


A evidência concreta de alguma sobrecarga de tempo de execução para VLA -., Pelo menos, com o GCC 4.4.2 em SPARC (Solaris 10)

Considere os dois arquivos a seguir:

vla.c - utilizando uma matriz de comprimento variável

#include <assert.h>
#include <stddef.h>
extern size_t identity_matrix(int n, int m);

size_t identity_matrix(int n, int m)
{
    int vla[n][m];
    int i, j;
    assert(n > 0 && n <= 32);
    assert(m > 0 && m <= 32);
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < m; j++)
        {
            vla[i][j] = 0;
        }
        vla[i][i] = 1;
    }
    return(sizeof(vla));
}

fla.c - utilizando um conjunto de comprimento fixo

#include <assert.h>
#include <stddef.h>
extern size_t identity_matrix(int n, int m);

size_t identity_matrix(int n, int m)
{
    int fla[32][32];
    int i, j;
    assert(n > 0 && n <= 32);
    assert(m > 0 && m <= 32);
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < m; j++)
        {
            fla[i][j] = 0;
        }
        fla[i][i] = 1;
    }
    return(sizeof(fla));
}

arquivo de Compilação e objeto tamanhos

Para fins de comparação, os nomes do array local são diferentes (vla vs fla), e as dimensões na matriz são diferentes quando ela é declarada -. Caso contrário, os arquivos são os mesmos

Eu compilei usando:

$ gcc -O2 -c -std=c99 fla.c vla.c

Os tamanhos dos arquivos objeto são um pouco diferentes - como medido tanto pelo 'ls' e por 'size':

$ ls -l fla.o vla.o
-rw-r--r--   1 jleffler rd          1036 Jan  9 12:13 fla.o
-rw-r--r--   1 jleffler rd          1176 Jan  9 12:13 vla.o
$ size fla.o vla.o
fla.o: 530 + 0 + 0 = 530
vla.o: 670 + 0 + 0 = 670

Eu não fiz testes extensivos para ver o quanto a sobrecarga é fixa e quanto é variável, mas há sobrecarga na utilização de um VLA.

Eu só quero saber se há alguma sobrecarga de utilização de matrizes de comprimento variável?

Nope

Pode o tamanho da matriz poderia ser passados ??via linha de comando argumento em tempo de execução?

Sim.

Por que é introduzido, em comparação com automático e alocar dinamicamente uma matriz?

automático somente alocados permite um tamanho fixo conhecido em tempo de compilação.

dinamicamente alocar (malloc) irá armazenar a matriz no pilha , que tem um espaço de memória grande, mas é mais lento para acesso.

VLA funciona colocando a matriz na pilha . Isso faz com que a alocação e acesso extremamente rápido, e a pilha é geralmente pequenas (de uns poucos KB), e quando o VLA transbordou a pilha, é indistinguível de uma recursão infinita.

Não deve haver muito pouca sobrecarga para Vlas (No máximo, deve resultar em um complemento para o ponteiro da pilha). alocação dinâmica requer gerenciamento de memória manual e é mais lenta do que a alocação baseada em pilha de um VLA, ea declaração "automático" de uma matriz requer uma expressão em tempo de compilação para o tamanho da matriz. No entanto, tenha em mente que, se um estouro de pilha ocorre, ele irá causar um comportamento indefinido, de modo a manter VLAs relativamente pequeno.

Você poderia passar o tamanho de uma matriz através de um argumento de linha de comando, mas você teria que escrever o código para lidar com isso sozinho.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top