gpt4 book ai didi

c - 如何循环结构体指针

转载 作者:行者123 更新时间:2023-11-30 17:28:35 25 4
gpt4 key购买 nike

我有一个看起来像这样的 for 循环:

for (i2 = 0; i2 < n_lines; i2++) {
statfs_full *f_tmp;
f_tmp = malloc(sizeof(statfs_full));
struct statfs *tmp;
tmp = malloc(sizeof(statfs));

statfs(fse[i2].fs_file, tmp);

merge_statfs_structs(tmp, &f_tmp);
strcpy(f_tmp->f_fstypename, fse[i2].fs_vsftype);
strcpy(f_tmp->f_mntonname, fse[i2].fs_file);
strcpy(f_tmp->f_mntfromname, fse[i2].fs_spec);

free(f_tmp);
free(tmp);

它是一个更大的函数的一部分。 statfs_full 是一个经过typdef 处理的结构,它只是添加了三个字段的标准struct statfs。对函数 merge_statfs_structs() 的调用使用 tmp 指向的标准结构中的值填充 f_tmp 指向的扩展结构。对 strcpy() 的三个调用填充了额外的三个字段。

代码编译正常,但我可以从一些 printf 调用中看到程序在调用 free() 时出现段错误。早些时候,我在循环外部进行了声明和 malloc 调用,并尝试将两个结构重置为 NULL,但这在第二次调用 merge_statfs_structs 时出现段错误。

所以我想我的问题是如何在每次循环时“重置” f_tmp 和 tmp 指向的结构?

编辑:添加 merge_statfs_structs 的源代码,以防它有密切关系...

int merge_statfs_structs(struct statfs *buf, statfs_full **buf_full) {
int i;
(*buf_full)->f_type = buf->f_type;
(*buf_full)->f_bsize = buf->f_bsize;
(*buf_full)->f_blocks = buf->f_blocks;
(*buf_full)->f_bfree = buf->f_bfree;
(*buf_full)->f_bavail = buf->f_bavail;
(*buf_full)->f_files = buf->f_files;
(*buf_full)->f_ffree = buf->f_ffree;
(*buf_full)->f_fsid = buf->f_fsid;
(*buf_full)->f_namelen = buf->f_namelen;
(*buf_full)->f_frsize = buf->f_frsize;

for (i = 0; i < 5; i++)
(*buf_full)->f_spare[i] = buf->f_spare[i];
return 0;
}

编辑2:添加mounted_fs_entrystruct statfs_full的定义:

#define FS_TYPE_LEN      90
#define MNT_FLAGS_LEN 256

typedef struct _mounted_fs_entry {
char fs_spec[PATH_MAX]; /* device or special file system path */
char fs_file[PATH_MAX]; /* mount point */
char fs_vsftype[FS_TYPE_LEN]; /* file system type */
char fs_mntops[MNT_FLAGS_LEN]; /* mount flags */
int fs_freq; /* dump */
int fs_passno; /* pass */
} mounted_fs_entry;

#if __WORDSIZE == 32
#define __WORD_TYPE int
#else /* __WORDSIZE == 64 */
#define __WORD_TYPE long int
#endif

typedef struct _statfs_full {
__WORD_TYPE f_type; /* type of filesystem */
__WORD_TYPE f_bsize; /* optimal transfer block size */
fsblkcnt_t f_blocks; /* total data blocks in filesystem */
fsblkcnt_t f_bfree; /* free blocks in fs */
fsblkcnt_t f_bavail; /* free blocks available to unprivileged user */
fsfilcnt_t f_files; /* total file nodes in filesystem */
fsfilcnt_t f_ffree; /* free file nodes in fs */
fsid_t f_fsid; /* filesystem id */
__WORD_TYPE f_namelen; /* maximum length of filenames */
__WORD_TYPE f_frsize; /* fragment size (since Linux 2.6) */
__WORD_TYPE f_spare[5];

/* these extra fields add path info as in the *BSD versions of statfs() */
char f_fstypename[FS_TYPE_LEN]; /* fs type name */
char f_mntonname[PATH_MAX]; /* directory on which mounted */
char f_mntfromname[PATH_MAX]; /* mounted file sytem */
} statfs_full;

我自己没有定义struct stafs,它是在/usr/include/sys/statfs.h中定义的,或者你也可以man statfsmounted_fs_entry 是 for 循环中 fse[i2] 引用的结构体。我在 github 上有整个文件 here如果你想看一下。

我在 gdb 中对此进行了更多的研究,在调用 free 期间,段错误发生在 glibc 内部。不幸的是,我的 glibc 不是用调试符号构建的,所以我无法使用 valgrind 来跟踪它。

最佳答案

我自己想出来了。将 malloc/free 调用移到循环之外,并在定义结构时摆脱了 typedef 语句。现在效果很好。这是更新后的代码(未删除错误检查):

struct statfs_ext *sas = malloc(sizeof(struct statfs_ext) * n_lines);

struct statfs_ext *f_tmp;
f_tmp = malloc(sizeof(struct statfs_ext));
if (f_tmp == NULL) {
perror("unable to malloc");
exit(EXIT_FAILURE);
}

struct statfs *s_tmp;
s_tmp = malloc(sizeof(struct statfs));
if (s_tmp == NULL) {
perror("unable to malloc");
exit(EXIT_FAILURE);
}

for (i2 = 0; i2 < n_lines; i2++) {

if (statfs(fse[i2].fs_file, s_tmp) != 0) {
perror("statfs() failed");
continue; /* might not be fatal */
}
merge_statfs_structs(s_tmp, &f_tmp);

strncpy(f_tmp->f_fstypename, fse[i2].fs_vsftype, FS_TYPE_LEN);
strncpy(f_tmp->f_mntonname, fse[i2].fs_file, PATH_MAX);
strncpy(f_tmp->f_mntfromname, fse[i2].fs_spec, PATH_MAX);

sas[i2] = *f_tmp;

}

free(s_tmp);
free(f_tmp);

以及结构定义:

#define FS_TYPE_LEN      90
#define MNT_FLAGS_LEN 256

struct mounted_fs_entry {
char fs_spec[PATH_MAX]; /* device or special file system path */
char fs_file[PATH_MAX]; /* mount point */
char fs_vsftype[FS_TYPE_LEN]; /* file system type */
char fs_mntops[MNT_FLAGS_LEN]; /* mount flags */
int fs_freq; /* dump */
int fs_passno; /* pass */
};

#if __WORDSIZE == 32
#define __WORD_TYPE int
#else /* __WORDSIZE == 64 */
#define __WORD_TYPE long int
#endif

struct statfs_ext {
__WORD_TYPE f_type; /* type of filesystem (see below) */
__WORD_TYPE f_bsize; /* optimal transfer block size */
fsblkcnt_t f_blocks; /* total data blocks in filesystem */
fsblkcnt_t f_bfree; /* free blocks in fs */
fsblkcnt_t f_bavail; /* free blocks available to unprivileged user */
fsfilcnt_t f_files; /* total file nodes in filesystem */
fsfilcnt_t f_ffree; /* free file nodes in fs */
fsid_t f_fsid; /* filesystem id */
__WORD_TYPE f_namelen; /* maximum length of filenames */
__WORD_TYPE f_frsize; /* fragment size (since Linux 2.6) */
__WORD_TYPE f_spare[5];

/* these extra fields add path info as in the *BSD versions of statfs() */
char f_fstypename[FS_TYPE_LEN]; /* fs type name */
char f_mntonname[PATH_MAX]; /* directory on which mounted */
char f_mntfromname[PATH_MAX]; /* mounted file sytem */
};

关于c - 如何循环结构体指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26007769/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com