我有一个看起来像这样的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'ed结构,只是一个标准struct statfs
,添加了三个字段。对函数merge_statfs_structs()
的调用使用tmp
指向的标准结构中的值填充f_tmp指向的扩展结构。对strcpy()
的三次调用填充了额外的三个字段。
代码编译好了,但我可以从一些printf调用看到该程序在free()
的调用中是segfaulting。之前我在循环外部进行了声明和malloc调用,并尝试将两个结构重置为NULL,但这是第二次调用merge_statfs_structs
时的segfaulting。
所以我想我的问题是如何通过循环每次'重置'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_entry
和struct 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 statfs
。 mounted_fs_entry
是for循环中fse[i2]
引用的结构。如果你想看一下,我在github here上有整个文件。
我在gdb中一直在玩这个,在免费调用期间,段内故障发生在glibc中。不幸的是我的glibc不是用调试符号构建的,所以我不能用valgrind来跟踪它。
答案 0 :(得分:0)
自己想出来。移动了循环外的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 */
};