热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

分配内存中的数据损坏

如何解决《分配内存中的数据损坏》经验,为你挑选了1个好方法。

每当我尝试访问使用所获取的内存中malloc的数据时,数据就会损坏

我正在编写一个程序,该程序读取Linux目录并将文件和子目录的名称写在“字符串数组”(c中的char **数组)中。它使用dirent.h诸如之类的功能进行操作readdir()。readdir返回一个Dirent结构,该结构的a dname[256]就是目标目录中文件/子目录的名称。我将Dirent字符串(char *)等同于char **数组中已分配位置的索引

我基本上有一个walk_path()函数,它读取目录条目并将它们的名称写入一个已分配的位置,然后返回该位置

data_t* walk_path(char* path) {
    int size = 0;

    if(path == NULL){
        printf("NULL path\n");
        return NULL;
    }
    struct dirent* entry;
    DIR* dir_l = opendir(path);

    if(dir_l == NULL) {
        char** data = (char**)malloc(sizeof(char*) * 2);
        data[0] = path;
        data_t* ret = (data_t*)malloc(sizeof(data_t));
        ret->data = data;
        ret->size = 1;
        return ret;
    }

    while((entry = readdir(dir_l)) != NULL) {
        if(!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
            continue;
        size++;
    }
    closedir(dir_l);

    char** data = (char**)malloc(sizeof(char*) * size + 1);
    int loop_v = 0;
    dir_l = opendir(path);

    while((entry = readdir(dir_l)) != NULL && loop_v d_name, ".") || !strcmp(entry->d_name, ".."))
            continue;
        data[loop_v] = entry->d_name;
        loop_v++;
    }

    closedir(dir_l);

    data_t* ret = (data_t*)malloc(sizeof(data_t*));
    ret->size = (size_t)size;
    ret->data = data;
    return ret;
}

以及合并路径功能,该功能可以获取两个目录并将其数据写入单个数组

char** merge_path(char* path, char* path2) {
    data_t* path_data = walk_path(path);
    data_t* path2_data = walk_path(path2);
    if(path_data == NULL || path2_data == NULL) {
        printf("Merge failed, couldn't get path data\n");
        return NULL;
    }

    char** new_dir_info = (char**)malloc(sizeof(char*) * (path2_data->size + path_data->size) );
    if(new_dir_info == NULL)
        return NULL;

    int loop = 0;
    while(loop size) {
        new_dir_info[loop] = path_data->data[loop];
        loop++;
    }
    loop = 0;
    while(loop size) {
        new_dir_info[loop + path_data->size] = path2_data->data[loop];
        loop++;
    }
    free(path_data);
    free(path2_data);
    return new_dir_info;
}

char**合并路径函数返回的数组始终具有损坏的数据,即字符数组中的字符已损坏,而不是指针本身,尽管我希望它具有从目录条目传递给它的字符串,但它具有随机字符串。

我单步执行代码,发现合并路径功能中的数据已损坏,错误的根源仍可能源自walk_path()



1> alk..:

这个

   data_t* ret = (data_t*)malloc(sizeof(data_t*));

必定是

   data_t* ret = (data_t*)malloc(sizeof(data_t));

通常,在C void指针中不需要强制转换,因此malloc可以删除代码中的所有强制转换,这使上面的行看起来像:

   data_t* ret = malloc(sizeof(data_t*));

排除此类错误的更多方法是,最好不要再将类型加倍以在to malloc的调用中使用malloc(),而是更好地使用变量与取消引用运算符一起分配给,例如:

   data_t* ret = malloc(sizeof *ret);

也是这条线

    data[loop_v] = entry->d_name;

复制指向条目名称的指针,而不是名称本身。

考虑使用

   data[loop_v] = strdup(entry->d_name);

它动态地为entry->d_name指向的位置分配空间。

替代代替

   char**data;

限定

   char (*data)[sizeof entry->d_name]; /* Array of pointers to char[as many char as entry->d_name is defined to have] */

要么

   char (*data)[sizeof ((struct dirent*)NULL)->d_name]; /* Array of pointers to char[as many char as entry->d_name is defined to have] */

并像这样分配给它(遵循上述建议的模式):

   data = malloc((size /* + 1 */) * sizeof *data); /* Not sure what the idea behind this +1 is. */

而不是

   data[loop_v] = strdup(entry->d_name);

   strcpy(data[loop_v], entry->d_name);

如果走这条路线,您需要相应地调整其定义data_t.data


推荐阅读
  • 本文深入探讨了Linux系统中网卡绑定(bonding)的七种工作模式。网卡绑定技术通过将多个物理网卡组合成一个逻辑网卡,实现网络冗余、带宽聚合和负载均衡,在生产环境中广泛应用。文章详细介绍了每种模式的特点、适用场景及配置方法。 ... [详细]
  • 本文详细介绍了如何在 Linux 平台上安装和配置 PostgreSQL 数据库。通过访问官方资源并遵循特定的操作步骤,用户可以在不同发行版(如 Ubuntu 和 Red Hat)上顺利完成 PostgreSQL 的安装。 ... [详细]
  • MySQL缓存机制深度解析
    本文详细探讨了MySQL的缓存机制,包括主从复制、读写分离以及缓存同步策略等内容。通过理解这些概念和技术,读者可以更好地优化数据库性能。 ... [详细]
  • MySQL 数据库迁移指南:从本地到远程及磁盘间迁移
    本文详细介绍了如何在不同场景下进行 MySQL 数据库的迁移,包括从一个硬盘迁移到另一个硬盘、从一台计算机迁移到另一台计算机,以及解决迁移过程中可能遇到的问题。 ... [详细]
  • Hadoop入门与核心组件详解
    本文详细介绍了Hadoop的基础知识及其核心组件,包括HDFS、MapReduce和YARN。通过本文,读者可以全面了解Hadoop的生态系统及应用场景。 ... [详细]
  • 本文详细介绍了VMware的多种认证选项,帮助你根据职业需求和个人技能选择最合适的认证路径,涵盖从基础到高级的不同层次认证。 ... [详细]
  • 本文由瀚高PG实验室撰写,详细介绍了如何在PostgreSQL中创建、管理和删除模式。文章涵盖了创建模式的基本命令、public模式的特性、权限设置以及通过角色对象简化操作的方法。 ... [详细]
  • 本文详细介绍了如何在Ubuntu系统中下载适用于Intel处理器的64位版本,涵盖了不同Linux发行版对64位架构的不同命名方式,并提供了具体的下载链接和步骤。 ... [详细]
  • 本文介绍如何通过更改软件源来提前体验Ubuntu 8.10,包括详细的配置步骤和相关注意事项。 ... [详细]
  • 本文详细记录了在银河麒麟操作系统和龙芯架构上使用 Qt 5.15.2 进行项目打包时遇到的问题及解决方案,特别关注于 linuxdeployqt 工具的应用。 ... [详细]
  • Linux设备驱动程序:异步时间操作与调度机制
    本文介绍了Linux内核中的几种异步延迟操作方法,包括内核定时器、tasklet机制和工作队列。这些机制允许在未来的某个时间点执行任务,而无需阻塞当前线程,从而提高系统的响应性和效率。 ... [详细]
  • 本文介绍如何在Linux服务器之间使用SCP命令进行文件传输。SCP(Secure Copy Protocol)是一种基于SSH的安全文件传输协议,支持从远程机器复制文件到本地服务器或反之。示例包括从192.168.45.147复制tomcat目录到本地/home路径。 ... [详细]
  • Composer Registry Manager:PHP的源切换管理工具
    本文介绍了一个用于Composer的源切换管理工具——Composer Registry Manager。该项目旨在简化Composer包源的管理和切换,避免与常见的CRM系统混淆,并提供了详细的安装和使用指南。 ... [详细]
  • PHP中去除换行符的多种方法及应用场景
    本文将详细介绍在PHP中去除换行符的各种方法,并结合实际应用场景进行说明。通过本文,您将了解如何根据不同操作系统的特点,选择最合适的换行符处理方式。 ... [详细]
  • 基于KVM的SRIOV直通配置及性能测试
    SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ... [详细]
author-avatar
花落酒未醉
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有