Pergunta

Com o seguinte pedaço de código, recebo um resultado muito estranho. Por que é o valor do último elemento de substituição de todos os elementos da matriz anteriores? i suspeitar que há um problema maior do que apenas este problema immmediate.

#include <stdio.h>

main()
{
    int i, cases;
    char num[1000000];

    scanf("%d", &cases);
    char* array[cases];

    //store inputs in array
    for(i=0; i<cases; i++)
    {
        scanf("%s", &num);
        array[i] = &num;
    }

    //print out array items and their memory addresses
    for(i=0; i<cases; i++)
    {
        printf("%d %s\n", i, array[i]);  //print (array index) (array value) 
        printf("%d %p\n", i, &array[i]); //print (array index) (array address) 
    }
}

Inputs:
3 <-- number of lines to follow
0   <-- put in array[0]
1   <-- put in array[1]
2   <-- put in array[2]

Outputs
0 3         <-- why is this being overwritten with the last element?
0 0013BCD0
1 3         <-- why is this being overwritten with the last element?
1 0013BCD4
2 3
2 0013BCD8

Nenhuma solução correta

Outras dicas

O resultado aqui é o array[i] = &num; linha que você está definindo o valor do elemento array[i] para o endereço da matriz num; desde array é uma matriz de char, eu suspeito que é truncar seu endereço de gama num, eo byte de ordem só acontece de ser um 3.

No entanto. Dito isto, seu char num [1000000] é forma hedionda, e você não deve fazer isso, em tudo. Alocar na pilha e escolha um número menor, pelo amor de Deus. Além disso, o scanf ( "% s", e num) não vai realmente dar-lhe o que quiser. Aqui vai uma dica; usar um loop getc () para ler os números; Isso evita a necessidade de fazer qualquer pré-alocação de uma matriz para scanf ().

É porque você está colocando em cada índice da matriz o mesmo endereço (o endereço de carvão num [1000000];).

É um erro que vai levar você a alocação dinâmica (calloc, malloc, novo, etc).

Felicidades!

Dentro do seu primeiro ciclo, você deve ser (mas não são) escrevendo cada entrada em um elemento diferente da matriz num; em vez você está sempre escrevendo para o mesmo lugar, ou seja, para &num.

char * array [casos];

Esta é alocado em tempo de compilação, não em tempo de execução. E os casos não é inicializado (embora eu acho que você quer que ele funcione de forma dinâmica de qualquer maneira.) Então você quer necessidade de pré-alocar a memória, ou se familiarizar com a família malloc de funções da biblioteca.

Substitua

//store inputs in array
for(i=0; i<cases; i++)
{
    scanf("%s", &num);
    array[i] = &num;
}

com

array[0] = num;
//store inputs in array
for(i=0; i<cases; i++)
{
    scanf("%s", array[i]);
    array[i+1] = array[i] + strlen(array[i]) + 1;
}

para digitalizar cada string no primeiro espaço disponível em num[], e definir o próximo elemento de array[] para apontar para o próximo espaço disponível. Agora seu printf() das cordas vai funcionar. O original foi a digitalização de cada corda para o início da num[].

Nota:.. scanf() com %s sem adornos é tão ruim quanto gets(), porque coloca nenhum limite na quantidade de dados que será sorvido em Não usá-lo em código verdadeiro

Substitua

    printf("%d %p\n", i, &array[i]); //print (array index) (array address) 

com

    printf("%d %p\n", i, (void*)(array[i])); //print (array index) (array address) 

para realmente imprimir os endereços armazenados no a[], em vez dos endereços dos elementos de a[]. O elenco é necessária porque %p espera um ponteiro-tovoid por isso você deve fornecer um.

Isso é o código que é fixo:

#include <stdio.h>

main(void)
{
    int i, cases;

    scanf("%d", &cases);
    char* array[cases];

    //store inputs in array
    for(i=0; i<cases; i++)
    {
        char *num = malloc(100000);
        scanf("%s", num);
        array[i] = num;
    }

    //print out array items and their memory addresses
    for(i=0; i<cases; i++)
    {
        printf("%d %s\n", i, array[i]);  //print (array index) (array value)
        printf("%d %p\n", i, (void*)&array[i]); //print (array index) (array address)
    }
    return 1;
}

Você pode também usar

char *num = calloc(100000, sizeof(char));

que é um pouco defensiva pouco. Eu não sei por que você precisa 100000. Você pode fazê-lo dinamicamente usando malloc. Isso implicará mais trabalho, mas é muito robusto.

O que é hapenning em seu código é que você armazenar a cadeia% s para o endereço de num que não muda, então você variedade atribuir [i] elemento para esse endereço. Atribuindo em C é nada mais, em seguida, guardar a referência, você não armazenar o elemento si- isso seria desperdício de espaço. Assim como todos os elementos do array apontar para o endereço (somente armazenar a referência), o valor na mudança endereço, portanto, assim que faz a referência, é por isso que todos eles estão mudando a 2 (não 3 como você disse em seu post).

É para essas coisas que C ++ parece ser feito. entrada de análise de usuário e dinâmicos alocações são feitas com mais segurança, e em uma brisa. Eu não consigo pensar em um sistema onde você tem esse tipo de interface do usuário, onde você não pode mudar para C ++.

Claro que, se este é apenas um trecho de teste de outro código que sofre com o problema, então é claro ...


Seus sofre de código de vários erros comuns para iniciantes C e coisas que não devem ser feitas dessa maneira hoje em dia.

Se bem entendi, você deseja salvar cordas de entrada do usuário sereval (seu exemplo de saída é um pouco enganador, porque você mostrar apenas números).

Você está a preparar a matriz para armazenar todos os casos (contar) ponteiros às cordas, mas você só está reservando memória para uma string. Você precisa fazer isso para cada corda, tão casos. Para manter as coisas simples em termos da lição "dinâmica de alocação de memória", eu recomendo fazê-lo dessa maneira:. char* array[cases][10000]; Isso dá-lhe casos cordas de 10k caracteres

Você provavelmente também não quer ter ponteiros separados para seus elementos do array. Isto começa a fazer sentido se você quiser classificar elementos de um array quando esses elementos são maiores do que o próprio ponteiros. Nesse caso, o ganho de desempenho é não ter movimento (cópia) grandes pedaços, mas apenas os ponteiros (geralmente 4 bytes). No seu caso, um int também é 4 bytes. E você não faz tipo assim mesmo:)

scanf() é perigoso, para dizer o mínimo. Em sua segunda aplicação, você está instruindo-o para escrever uma string para o endereço do array. Este parece ser um simples erro, mas pode levar a muitos problemas. Você provavelmente vai querer fazê-lo dessa maneira: scanf("%d", &array[i]); (Infelizmente, eu não tenho um compilador na mão, então eu não estou 100% de certeza). soltar a linha seguinte:)


Pergunta para especialistas Markdown:? Por que é tão maldita impossível ter LISTAS combinados com código de blocos

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