no se puede ejecutar este programa en cmd.exe

Estoy tratando de copiar algunos textos de un archivo y guardarlos en los miembros de la estructura, ejecuto mi programa en cmd.exe y se bloqueó, pero cuando lo ejecuto en Codeblocks o Visual Studio funciona.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct AMIGOS 
{ 
    char nom[' '];
    char apellido[' '];
    char nompila[' '];
    char tel[' '];
    char correo[' '];
    char dir[' '];
    char fecha[' ']; 
};

int main()
{
    struct AMIGOS reg;
    char registro[128];

    char**datos;
    char*dato;
    datos = (char**)malloc(10*sizeof(char**));
    int tam;
    int i=0;

    FILE* pt = fopen("arch.txt","r");
    if(pt==NULL)
    {
        printf("filenotfound\n");
    }
    else
    {
        while(fgets(registro,128,pt))
        {
            dato = strtok(registro,"|");
            while(dato)
            {
                tam = strlen(dato);
                datos[i] = (char *)malloc(tam);
                memcpy(datos[i],dato,tam);
                datos[i][tam]=0;
                i++;
                datos[i]=0;
                dato = strtok(0,"|");
            }    
        }
        strcpy(reg.nom,datos[0]);
        strcpy(reg.apellido,datos[1]);
        strcpy(reg.nompila,datos[2]);
        strcpy(reg.fecha,datos[3]);
        strcpy(reg.tel,datos[4]);
        strcpy(reg.correo,datos[5]);
        strcpy(reg.dir,datos[6]);

        printf("%s\n",reg.nom);
        printf("%s\n",reg.apellido);
        printf("%s\n",reg.nompila);
        printf("%s\n",reg.fecha);
        printf("%s\n",reg.tel);
        printf("%s\n",reg.correo);
        printf("%s\n",reg.dir);
    }    
}

el texto en el archivo:

kevin|clark|ns|15 de marzo de 2001|5555555|l@mail.com|calle 123

¿Alguien sabe por qué falla cuando intento ejecutarlo en cmd.exe?

preguntado el 22 de mayo de 12 a las 09:05

¿Quiere decir que cuando ejecuta el ejecutable compilado se bloquea, pero cuando ejecuta su código desde Visual Studio, funciona? -

Porque escribes char nom[' ']? -

4 Respuestas

Esto es escribir más allá del final de la matriz:

tam = strlen(dato);
datos[i] = (char *)malloc(tam);
memcpy(datos[i],dato,tam);
datos[i][tam]=0;                 <---- 'tam -1' is the last element

Debe agregar un carácter adicional para almacenar el terminador nulo, o simplemente puede usar strdup():

datos[i] = strdup(dato);

contestado el 22 de mayo de 12 a las 09:05

Y entonces la solución es pasar tam+1 a malloc - David Heffernan

No sé por qué funciona en Visual Studio pero falla en Cmd Line. Pero, hay algunos problemas en su código:

        tam = strlen(dato); 
        datos[i] = (char *)malloc(tam); //You are not allocating memory for '\0' character
        memcpy(datos[i],dato,tam);
        datos[i][tam]=0; //So this is effectively an array out of bound write

debiera ser

        tam = strlen(dato); 
        datos[i] = (char *)malloc(tam+1); 
        memcpy(datos[i],dato,tam);
        datos[i][tam]=0; 

contestado el 22 de mayo de 12 a las 09:05

Aquí hay un par de problemas:

datos = (char**)malloc(10*sizeof(char**));

Realmente quieres decir:

datos = (char**)malloc(10*sizeof(char*));

(Siguiendo el modismo C normal de:

var = malloc(n * sizeof *var);

evitaría este error. En la práctica, es probable que los tamaños sean los mismos, pero en principio es incorrecto. También tenga en cuenta que lanzar el resultado de malloc también está mal visto en C.)

tam = strlen(dato);
datos[i] = (char *)malloc(tam);
memcpy(datos[i],dato,tam);
datos[i][tam]=0;

Estás desbordando tu búfer. usted asignó tam bytes de memoria, luego copiaste tam bytes en él, pero luego intenta terminarlo con NUL. Necesitas asignar tam + 1 bytes

Como otros consejos:

  • Su uso de strcpy es inseguro; no puede garantizar que la entrada tokenizada no hará que también desborde esos búferes.
  • fgets(registro,128,pt) sería mejor como fgets(registro, sizeof registro, pt).

contestado el 22 de mayo de 12 a las 09:05

Esta:

char nom[' '];

es un código muy extraño, es casi seguro que no hace lo que esperas. Me interesaría escuchar la motivación de este código.

Básicamente declarará nom como una matriz de caracteres, cuya longitud viene dada por el valor entero del carácter SPACE . Asumiendo una máquina ASCII, esto será equivalente a:

char nom[32];

contestado el 22 de mayo de 12 a las 09:05

It is extraño de hecho, pero no explica por qué el programa falla. - eitan t

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.