Pergunta

Eu estou tentando imitar o seguinte código Java:

int[][] multi; // DIMENSIONS ARE UNKNOWN AT CREATION TIME
// LATER ON...
multi = new int[10][];
multi[5] = new int[20];
multi[5][11] = 66;
// LATER ON...
multi = null; // PROPER WAY OF FREEING EVERYTHING

Já saiu com a seguinte versão Objective-C:

int* *multi;
//
multi = malloc(10 * sizeof(int*));
multi[5] = (int *) malloc(20 * sizeof(int));
multi[5][11] = 66;
//
free(multi[5]);
free(multi);

Assim, em primeiro lugar, eu gostaria de saber se é o melhor caminho a percorrer. E principalmente: não consigo encontrar uma maneira de memória livre de alguma forma "automática", ou seja, o código a seguir está causando exceções de tempo de execução no iPhone:

for (int i = 0; i < 10; i++)
{
    if (multi[i] != NULL) free(multi[i]);
}
Foi útil?

Solução

Free não zero, o endereço de memória no ponteiro, ele simplesmente invalida-lo. Então, se você estiver executando esse loop mais de uma vez, você vai ter exceções quando você tenta liberar memória que já foi invalidada. Você pode usar um NSPointerArray ou envolver seus inteiros em objetos e usar um NSMutableArray para seus propósitos, mas se você só quer usar o que você tem, e você estiver executando o loop mais de uma vez, você vai ter que fazer algo como:

int **multi;
multi = calloc(10, sizeof(int*));
multi[5] = calloc(20, sizeof(int));
//
multi[5][11] = 66;
//
for( int i = 0; i < 10; i++ ) {
  if( multi[i] ) {
    free(multi[i]);
    multi[i] = NULL;
  }
}
//
free(multi);

Desta forma, se o loop é executado mais de uma vez, você não vai falhar. Além disso, eu usar calloc em vez de malloc porque vai definir todos os ponteiros para NULL e inteiros a 0. O primeiro parâmetro é o tamanho da matriz que você quer (no seu caso) eo segundo parâmetro é o tamanho do tipo (assim nenhuma multiplicação é necessária).

Outras dicas

Em primeiro lugar, a solução sugerida na pergunta não é específica para Objective-C, este é padrão tradução C. A C do código Java parece correto.

Em segundo lugar, o sugeriu lata livre "automático" não trabalho: malloc () não inicializar a memória alocada. Gostaria de usar calloc () em vez, ou adicionar um memset () depois de malloc ().

Em terceiro lugar, para uma versão Objective-C, eu consideraria um objeto NSMutableArray preenchida com NSMutableArray próprios objetos preenchidos com objetos NSNumber. Por seu objetivo, eu acho que a versão C é OK.

Você pode fazer uma matriz unidimensional e, em seguida, usar um índice baseado fora de seus dois valores. Dessa forma, terá menos código de inicialização para lidar com eles.

Além disso, se você adiar a inicialização multi até saber as dimensões, você pode simplesmente inicialize-o como se fosse uma matriz estática, em vez de uma de tamanho variável.

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