小哥哥咯 2018-05-07 16:24 采纳率: 100%
浏览 1298
已采纳

strcpy复制数组,程序异常奔溃

问题:解释一下我备注错误的地方为什么会使程序崩溃。
图片说明

开发IDE:codeblock17.12
链接:https://pan.baidu.com/s/1wwoP4v_Y5xYJtH7WZIWjdw 密码:gm87

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. typedef struct element
  5. {
  6. char *key;
  7. char *content;
  8. }element;
  9. char buf[2048]={0};
  10. int get_elements(element **p,char * file_name)
  11. {
  12. FILE * fp=fopen(file_name,"r");
  13. if(fp==NULL)
  14. {
  15. printf("打开文件失败!");
  16. return -1;
  17. }
  18. *p=(element*)malloc(sizeof(element));
  19. //char buf[2048]={0};
  20. int index=0;
  21. while(!feof(fp))
  22. {
  23. if(fgets(buf,sizeof(buf),fp)!=NULL)
  24. {
  25. (*p)[index].key=(char *)calloc(strlen(buf),sizeof(char));
  26. //strcpy((*p)[index].key,buf);//错误
  27. //strncpy((*p)[index].key,buf,strlen(buf));//错误
  28. //strcpy((*p)[index].key,&buf[0]);//错误
  29. strcpy((*p)[index].key,&buf[1]);//正确
  30. memset(buf,0,sizeof(buf));
  31. }
  32. if(fgets(buf,sizeof(buf),fp)!=NULL)
  33. {
  34. (*p)[index].content=(char *)calloc(strlen(buf),sizeof(char));
  35. //strcpy((*p)[index].content,buf);
  36. strcpy((*p)[index].content,&buf[6]);
  37. memset(buf,0,sizeof(buf));
  38. }
  39. printf("%s%s",(*p)[index].key,(*p)[index].content);
  40. index++;
  41. if((*p=(element*)realloc(*p,sizeof(element)*(index+1))) == NULL)
  42. {
  43. puts("error");
  44. return -1;
  45. }
  46. //memset(*p+index,0,sizeof(element));
  47. }
  48. fclose(fp);
  49. return index;
  50. }
  51. int search_element(element *p,int n,const char * key)
  52. {
  53. int i=0;
  54. for(i=0;i<n;i++)
  55. {
  56. //if(strcmp(p[i].key,key)==0)//p[i].key[3]是'\n'字符,key[3]是'\0'字符
  57. if (strncmp(p[i].key, key, strlen(key)) == 0)
  58. {
  59. printf("%s",p[i].content);
  60. return 1;
  61. }
  62. }
  63. return -1;
  64. }
  65. //最好还是传指针的地址,不然就是野指针
  66. int free_elements(element *p,int n)
  67. {
  68. int i=0;
  69. for(i=0;i<n;i++)
  70. {
  71. if (p[i].key)
  72. free(p[i].key);
  73. if (p[i].content)
  74. free(p[i].content);
  75. }
  76. free(p);
  77. return 0;
  78. }
  79. int main()
  80. {
  81. char file_name[]="dict.txt";
  82. element *p=NULL;
  83. int n = get_elements(&p,file_name);//将词典的内容读到内存
  84. search_element(p,n,"you");
  85. free_elements(p,n);
  86. return 0;
  87. }

工程文件包:
链接:https://pan.baidu.com/s/1FfHerOqcVlGoP3-vSvXMIA 密码:b1gu

展开全部

  • 写回答

4条回答 默认 最新

  • weixin_41475349 2018-05-07 17:59
    关注

    如果dict.txt是如下格式
    key:content
    可以做如下修改,代码中对于一些问题做出了建议,不对之处可以讨论
    #include
    #include
    #include
    typedef struct element
    {
    char *key;
    char *content;
    }element;

    char buf[2048]={0};
    int get_elements(element **p, char * file_name)
    {
    FILE * fp=fopen(file_name,"r");
    if(fp==NULL)
    {
    printf("打开文件失败!\n");
    return -1;
    }
    //*p=(element*)malloc(sizeof(element));
    //char buf[2048]={0};
    //index为string.h库中函数名,在包含该库的时候建议不使用
    int iIndex=0;
    while(!feof(fp))
    {
    //将内存分配放在这里,确保文件有内容可读的时候才分配内存
    if((*p=(element*)realloc(*p,sizeof(element)*(iIndex+1))) == NULL)
    {
    puts("error");
    return -1;
    }

        memset(buf,0,sizeof(buf));
        if(fgets(buf,sizeof(buf),fp)!=NULL) //读取文件一次,读取
        {
            (*p)[iIndex].key=(char *)calloc(strlen(buf),sizeof(char));
            //strcpy((*p)[index].key,buf);//错误
            //strncpy((*p)[index].key,buf,strlen(buf));//错误
            //strcpy((*p)[index].key,&buf[0]);//错误
            char *sepIndex = index(buf, ':');
            //查找key
            strncpy((*p)[iIndex].key, buf, sepIndex-buf);//strcpy很容易造成内存益处,建议使用strncpy
            //查找content
            (*p)[iIndex].content=(char *)calloc(strlen(buf),sizeof(char));
            strncpy((*p)[iIndex].content, sepIndex+1, strlen(sepIndex+1)); 
            sepIndex = NULL;
    

    /*
    if(fgets(buf,sizeof(buf),fp)!=NULL)
    {
    (*p)[index].content=(char *)calloc(strlen(buf),sizeof(char));
    //strcpy((*p)[index].content,buf);
    strcpy((*p)[index].content,&buf[6]);
    memset(buf,0,sizeof(buf));
    }
    */
    printf("%s: %s",(*p)[iIndex].key,(*p)[iIndex].content);
    }

        ++iIndex;
    

    /*
    //如果扩展内存放这里,意味着如果已经到了文件尾,还是继续分配了内存,造成资源浪费
    if((*p=(element*)realloc(*p,sizeof(element)*(iIndex+1))) == NULL)
    {
    puts("error");
    return -1;
    }
    //memset(*p+index,0,sizeof(element));
    /
    }
    fclose(fp);
    return iIndex;
    }
    int search_element(element *p,int n,const char * key)
    {
    int i=0;
    for(i=0;i<n;i++)
    {
    //if(strcmp(p[i].key,key)==0)//p[i].key[3]是'\n'字符,key[3]是'\0'字符
    if (strncmp(p[i].key, key, strlen(key)) == 0)
    {
    printf("%s",p[i].content);
    return 1;
    }
    }
    return -1;
    }
    //最好还是传指针的地址,不然就是野指针
    //这里你只释放了结构体内部的指针,对于结构体本身的指针并没有释放
    /

    int free_elements(element *p,int n)
    {
    int i=0;
    for(i=0;i<n;i++)
    {
    if (p[i].key)
    free(p[i].key);
    if (p[i].content)
    free(p[i].content);
    }
    free(p);
    return 0;
    }
    */
    int free_elements(element **p,int n)
    {
    int i=0;
    for(i=0;i<n;i++)
    {
    if ((*p)[i].key)
    free((*p)[i].key);
    if ((*p)[i].content)
    free((*p)[i].content);
    }
    free(*p);
    *p = NULL;
    return 0;
    }
    int main()
    {
    char file_name[]="dict.txt";
    element *p=NULL;
    int n = get_elements(&p,file_name);//将词典的内容读到内存
    search_element(p,n,"you");
    free_elements(&p,n);
    return 0;
    }

    展开全部

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)
编辑
预览

报告相同问题?

手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部