以下代码将指向FILE类型的数组的指针传递给函数,在访问数组时导致分段错误(gcc,在Ubuntu 12.04 LTS上)。
在main中,请输入以下代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
FILE **ptr_rdfile;
//Function declares
FILE ** open_files(int argc, char *argv[]);
int parse_files(FILE **ptr_rdfile[], int argc, char *argv[]);
//check for required input
if( argc < 2 )
{
printf( "Error - must enter at least one binary filename to read in.\n" );
return 1;
}
if( argc > 5 )
{
printf( "Error - maximum number of binary filenames %d.\n", MAX_FILES );
return 1;
}
//open files specified on cmd line
ptr_rdfile = open_files(argc, argv);
if( ptr_rdfile == NULL )
{
printf( "Exiting program\n" );
return 1;
}
//parse file contents into corresponding array of structs, print to stdout
if( parse_files(&ptr_rdfile, argc, argv) !=0 )
{
printf( "Parse Failed - Exiting program\n" );
return 1;
}
函数open_files如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
FILE ** open_files(int argc, char *argv[])
{
int i;
FILE **ptr_rdfile;
ptr_rdfile = malloc( sizeof(FILE *) * (argc-1));
if( ptr_rdfile == NULL )
{
printf("Error: Not enough memory\n");
getchar();
return NULL;
}
i=1;
for( i=1; i<argc; i++)
{
errno=0;
ptr_rdfile[i-1] = fopen(argv[i],"rb");
//printf( "ptr_rdfile[%d]:%p\n", (i-1), ptr_rdfile[i-1]);
if (!ptr_rdfile[i-1])
{
printf( "Unable to open file - is file name correct??? Errno = %d, %s.\n", errno, strerror(errno) );
return NULL;
}
}
return ptr_rdfile;
}
函数parse_files如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
int parse_files(FILE **ptr_rdfile[], int argc, char *argv[])
{
unsigned int j;
signed int i;
struct prod_rec
{
int ver;
char type_code[20];
unsigned int unit_ID;
float price;
};
struct prod_rec prod[argc];
i=0;
for( i=0; i<argc-1; i++)
{
//printf( "fread: i = %d", i );
if (fread(&prod[i], sizeof(struct prod_rec), 1, *ptr_rdfile[i]) != 1)
{
printf( "error writing sturct: Errno = %d, %s.\n", errno, strerror(errno) );
}
}
}
在调用parse_file之前在main中运行以下printf(以及各种迭代),
printf( "parse_files: ptr_rdfile = %p\n *ptr_rdfile = %p\n ptr_rdfile[0] = %p\n ptr_rdfile[1] = %p\n (void*)&ptr_rdfile[0] = %p\n (void*)&ptr_rdfile[1] = %p\n *ptr_rdfile[0] = %p\n *ptr_rdfile[1] = %p\n, **ptr_rdfile = %p\n **ptr_rdfile[1] = %p\n", ptr_rdfile, *ptr_rdfile, ptr_rdfile[0], ptr_rdfile[1], (void*)&ptr_rdfile[0], (void*)&ptr_rdfile[1], *ptr_rdfile[0], *ptr_rdfile[1], **ptr_rdfile, **ptr_rdfile );
显示以下内容:
ptr_rdfile = 0x804c008
*ptr_rdfile = 0x804c018
ptr_rdfile[0] = 0x804c018
ptr_rdfile[1] = 0x804c180
(void*)&ptr_rdfile[0] = 0x804c008
(void*)&ptr_rdfile[1] = 0x804c00c
从main导入parse_files,使用gdb,ptr_rdfile具有以下内容:
(gdb) print ptr_rdfile[1]
$1 = (FILE **) 0xb7e52e55
(gdb) print *ptr_rdfile
$2 = (FILE **) 0x804c008
(gdb) print **ptr_rdfile
$3 = (FILE *) 0x804c018
(gdb) print ***ptr_rdfile
$4 = {_flags = -72539000, ...
print *ptr_rdfile[1]
$11 = (FILE *) 0x5b18c483
除了我在上面的颠簸之外,我认为ptr_rdfile [0]似乎是好的,但不是ptr_rdfile [1]。
我还为ptr_rdfile尝试了以下格式:
//function declare:
int parse_files(FILE ***ptr_rdfile, int argc, char *argv[]);
function call:
if( parse_files(&ptr_rdfile, argc, argv) !=0 )
上面导致同样的错误。
在我将上面的代码移到parse_files之前,我在main中使用了该代码,并且它与ptr_rdfile的相同声明一起正常工作,并且以下调用fread:
if (fread(&prod[i], sizeof(struct prod_rec), 1, ptr_rdfile[i]) != 1)
转到单独的功能,基于我在本网站上研究过的讨论。将指针数组传递给函数,我就完成了上述尝试,但我显然在这里遗漏了一些东西......
任何调试建议都表示赞赏。
谢谢。
更新: 我尝试了类似@ user3629249建议的内容,这导致了以下编译警告:
$ gcc -g -Wall -Wextra -o parsebin.out open_files.c parse_files.c parsebin.c
parsebin.c: In function ‘main’:
parsebin.c:41:3: warning: passing argument 1 of ‘parse_files’ from incompatible pointer type [enabled by default]
parsebin.c:17:7: note: expected ‘struct FILE **’ but argument is of type ‘struct FILE ***’
我刚刚尝试使用以下代码(func declare,func call和function code):
主要:
//func declare:
int parse_files(FILE **ptr_myfile, int argc, char *argv[]);
//func call:
if( parse_files(ptr_myfile, argc, argv) !=0 )
在parse_files中:
int parse_files(FILE **ptr_myfile, int argc, char *argv[])
{
...
if (fread(&prod[i], sizeof(struct prod_rec), 1, ptr_myfile[i]) != 1)
嗯,当然,我必须在之前的尝试中搞砸了一些东西,因为上面似乎工作正常。哇,谢谢user3629249和其他所有人的亲切帮助和指导。在这个帮助下,我想我理解这里的指针方案。再次感谢你。