0

我试图从文件中复制一些文本并将它们保存在结构成员中,我在 cmd.exe 上运行我的程序并且它崩溃了,但是当我在代码块或 Visual Studio 上运行它时它可以工作,

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

文件上的文字:

kevin|clark|ns|2001 年 3 月 15 日|5555555|l@mail.com|123 街

当我尝试在 cmd.exe 上运行它时,有人知道它为什么会崩溃吗?

4

4 回答 4

2

这是超出数组末尾的写入:

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

您需要添加一个额外的字符来存储空终止符,或者您可以只使用strdup()

datos[i] = strdup(dato);
于 2012-05-22T08:51:58.130 回答
1

我不知道为什么它在 Visual Studio 中有效,但在 Cmd Line 中崩溃。但是,您的代码中存在一些问题:

        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

应该

        tam = strlen(dato); 
        datos[i] = (char *)malloc(tam+1); 
        memcpy(datos[i],dato,tam);
        datos[i][tam]=0; 
于 2012-05-22T08:53:58.487 回答
1

这里有几个问题:

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

你实际上的意思是:

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

(按照正常的 C 习惯用法:

var = malloc(n * sizeof *var);

会避免这个错误。在实践中,大小可能相同,但原则上是错误的。另请注意,malloc在 C 中强制转换 of 的结果也是不受欢迎的。)

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

你的缓冲区溢出了。您分配tam了内存字节,然后将字节复制tam到其中,但随后您尝试 NUL 终止它。您需要分配tam + 1字节。

作为其他建议:

  • 您的使用strcpy不安全;您不能保证标记化的输入也不会导致您溢出这些缓冲区。
  • fgets(registro,128,pt)会更好fgets(registro, sizeof registro, pt)
于 2012-05-22T08:54:07.300 回答
0

这个:

char nom[' '];

是非常奇怪的代码,几乎可以肯定它不会像你期望的那样做。我很想听听这段代码的动机。

它将基本上声明nom为一个字符数组,其长度由字符的整数值给出SPACE。假设一台 ASCII 机器,这将等价于:

char nom[32];
于 2012-05-22T08:47:18.333 回答