Pregunta

Con el siguiente código, obtengo un resultado muy extraño.¿Por qué el valor del último elemento sobrescribe todos los elementos de la matriz anterior?Sospecho que hay un problema mayor que este problema inmediato.

#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

No hay solución correcta

Otros consejos

El resultado aquí es la línea array[i] = &num; estás estableciendo el valor del array[i] elemento a la dirección del num formación;desde array es una matriz de caracteres, sospecho que está truncando tu num dirección de matriz, y el byte de orden inferior resulta ser un 3.

Sin embargo.Dicho esto, tu char num[1000000] es una forma espantosa y no deberías hacer eso en absoluto.Asigne en el montón y elija un número menor, por el amor de Dios.Además, scanf("%s", &num) en realidad no le dará lo que desea.He aquí una pista;use un bucle getc() para leer los números;esto evita la necesidad de realizar una preasignación de una matriz para scanf().

Es porque usted está poniendo en todos los índices de la matriz de la misma dirección (la dirección de carbón num [1000000];).

Es un error que le llevará a la asignación dinámica (calloc, malloc, nuevo, etc).

Saludos!

Dentro de su primer bucle, debería ser (pero que no lo son) escribir cada entrada en un elemento diferente de la matriz num; en cambio siempre se está escribiendo en el mismo lugar, es decir, a &num.

char * array [casos];

Esto se asigna en tiempo de compilación, no en tiempo de ejecución. Y los casos no se ha inicializado (aunque creo que quiere que funcione de forma dinámica de todos modos.) Así que o bien tienen que asignar previamente la memoria, o familiarizarse con la familia de funciones de biblioteca malloc.

Reemplazar

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

con

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 escanear cada cadena en el primer espacio disponible en num[], y establezca el siguiente elemento de array[] para que apunte al siguiente espacio disponible. Ahora su printf() de las cuerdas va a funcionar. El original estaba examinando cada cadena en el inicio de num[].

Nota:.. scanf() con %s sin adornos es tan malo como gets(), porque pone ningún límite en la cantidad de datos que se sorbió en No lo utilice en el código real

Reemplazar

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

con

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

para imprimir en realidad las direcciones almacenadas en a[], en lugar de las direcciones de los elementos de a[]. Se requiere que el yeso porque %p espera un puntero-tovoid por lo que debe proporcionar una.

Eso es el código que se fija:

#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;
}

Puede también utilizar

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

que es un poco poco a la defensiva. No sé por qué necesita 100000. Puede hacerlo de forma dinámica usando malloc. Esto implica más trabajo, pero es muy robusto.

Lo que se hapenning en su código es que almacene la cadena% s para la dirección de num que no cambia, entonces se asigna array [i] elemento a esa dirección. Asignación en C no es otra cosa a continuación, almacenar la referencia, no almacena el elemento misma- esto sería desperdicio de espacio. De manera que todos los elementos de la matriz apunte a la dirección (sólo almacenar la referencia), el valor en el cambio de dirección, por lo tanto también lo hace la referencia, es por eso que todos ellos están cambiando a 2 (no 3 como ha afirmado en su puesto).

Es para este tipo de cosas que C ++ parece estar hecho. análisis de la entrada del usuario y las asignaciones dinámicas se realizan de forma más segura, y en una brisa. No puedo pensar en un sistema en el que tienes ese tipo de interfaz de usuario, donde no se podía cambiar a C ++.

Por supuesto, si esto es sólo un extracto de las pruebas de otro código que sufre del problema, entonces, por supuesto ...


Su código adolece de varios errores comunes para los principiantes C y cosas que no se deben hacer de esa manera hoy en día.

Si he entendido bien, que desea guardar las cadenas de entrada de usuario sereval (su salida de ejemplo es un poco engañoso, ya que muestran sólo los números).

Usted se está preparando la matriz para contener todos los casos (recuento) de punteros a cadenas, pero sólo se está reservando memoria para una cadena. Que tiene que hacer que por cada cadena, por lo casos. Para simplificar las cosas en términos de la lección "asignación dinámica de memoria", recomiendo hacerlo de esa manera:. char* array[cases][10000]; Eso le da Casos cadenas de caracteres 10k

Es probable que también no quieren tener punteros separadas a sus elementos de la matriz. Esto empieza a tener sentido si desea ordenar los elementos de un array cuando estos elementos son más grandes que la propia punteros. En ese caso, su ganancia en el rendimiento no es tener movimiento (copia) trozos grandes, pero sólo los punteros (generalmente 4 bytes). En su caso, también un int es de 4 bytes de longitud. Y no ordenar todos modos:)

scanf() es peligroso, por decir lo menos. En su segunda aplicación, se indica que para escribir una cadena a la dirección de la matriz. Esto parece ser un simple error, pero puede conducir a muchos problemas. Es posible que desee hacerlo de esa manera: scanf("%d", &array[i]); (Por desgracia, no tengo un compilador a la mano, así que no estoy seguro al 100%). dejar caer la línea siguiente:)


Pregunta a especialistas de rebajas:? ¿Por qué es tan malditamente imposible tener listas combinadas con el código de bloques

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top