C语言中的分段错误
当我运行我的程序时,我得到系统崩溃“分段故障”消息 我想知道是否有办法确切地知道导致系统崩溃的指令(代码行)分段故障消息“ 代码==>C语言中的分段错误,c,linux,ip-address,C,Linux,Ip Address,当我运行我的程序时,我得到系统崩溃“分段故障”消息 我想知道是否有办法确切地知道导致系统崩溃的指令(代码行)分段故障消息“ 代码==> #include "GeoIP.h" int main() { FILE *f; char ipAddress[30]; char expectedCountry[3]; char expectedCountry3[4]; const char *returnedCountry; GeoIP *gi; i
#include "GeoIP.h"
int main()
{
FILE *f;
char ipAddress[30];
char expectedCountry[3];
char expectedCountry3[4];
const char *returnedCountry;
GeoIP *gi;
int failed = 0;
int test_num = 1;
int i;
for (i = 0; i < 2; ++i) {
if (0 == i) {
/* Read from filesystem, check for updated file */
gi = GeoIP_open("/usr/share/GeoIP/GeoIP.dat",
GEOIP_STANDARD | GEOIP_CHECK_CACHE);
} else {
/* Read from memory, faster but takes up more memory */
gi = GeoIP_open("/usr/share/GeoIP/GeoIP.dat", GEOIP_MEMORY_CACHE);
}
if (gi == NULL) {
fprintf(stderr, "Error opening database\n");
exit(1);
}
/* make sure GeoIP deals with invalid query gracefully */
returnedCountry = GeoIP_country_code_by_addr(gi, NULL);
if (returnedCountry != NULL) {
fprintf(stderr,
"Invalid Query test failed, got non NULL, expected NULL\n");
failed = 1;
}
returnedCountry = GeoIP_country_code_by_name(gi, NULL);
if (returnedCountry != NULL) {
fprintf(stderr,
"Invalid Query test failed, got non NULL, expected NULL\n");
failed = 1;
}
f = fopen("/home/aa/test/country_test.txt", "r");
while (fscanf(f, "%s%s%s", ipAddress, expectedCountry, expectedCountry3)
!= EOF) {
returnedCountry = GeoIP_country_code_by_addr(gi, ipAddress);
if (returnedCountry == NULL
|| strcmp(returnedCountry, expectedCountry) != 0) {
fprintf(stderr,
"Test addr %d for %s failed, got %s, expected %s\n",
test_num, ipAddress, returnedCountry, expectedCountry);
failed = 1;
}
returnedCountry = GeoIP_country_code_by_name(gi, ipAddress);
if (returnedCountry == NULL
|| strcmp(returnedCountry, expectedCountry) != 0) {
fprintf(stderr,
"Test name %d for %s failed, got %s, expected %s\n",
test_num, ipAddress, returnedCountry, expectedCountry);
failed = 1;
}
returnedCountry = GeoIP_country_code3_by_addr(gi, ipAddress);
if (returnedCountry == NULL
|| strcmp(returnedCountry, expectedCountry3) != 0) {
fprintf(stderr,
"Test addr %d for %s failed, got %s, expected %s\n",
test_num, ipAddress, returnedCountry, expectedCountry);
failed = 1;
}
returnedCountry = GeoIP_country_code3_by_name(gi, ipAddress);
if (returnedCountry == NULL
|| strcmp(returnedCountry, expectedCountry3) != 0) {
fprintf(stderr,
"Test name %d for %s failed, got %s, expected %s\n",
test_num, ipAddress, returnedCountry, expectedCountry);
failed = 1;
}
test_num++;
}
fclose(f);
f = fopen( "/home/aa/test/country_test2.txt", "r");
while (fscanf(f, "%s%s", ipAddress, expectedCountry) != EOF) {
returnedCountry = GeoIP_country_code_by_addr(gi, ipAddress);
if (returnedCountry == NULL
|| strcmp(returnedCountry, expectedCountry) != 0) {
fprintf(stderr, "Test addr %d %s failed, got %s, expected %s\n",
test_num, ipAddress, returnedCountry, expectedCountry);
failed = 1;
}
test_num++;
}
fclose(f);
f = fopen( "/home/aa/test/country_test_name.txt", "r");
while (fscanf(f, "%s%s", ipAddress, expectedCountry) != EOF) {
returnedCountry = GeoIP_country_code_by_name(gi, ipAddress);
if (returnedCountry == NULL
|| strcmp(returnedCountry, expectedCountry) != 0) {
fprintf(stderr, "Test addr %d %s failed, got %s, expected %s\n",
test_num, ipAddress, returnedCountry, expectedCountry);
failed = 1;
}
test_num++;
}
fclose(f);
GeoIP_delete(gi);
}
return failed;
}
#包括“GeoIP.h”
int main()
{
文件*f;
字符地址[30];
char expectedCountry[3];
char expectedCountry3[4];
const char*返回的国家/地区;
GeoIP*gi;
int失败=0;
int test_num=1;
int i;
对于(i=0;i<2;++i){
如果(0==i){
/*从文件系统读取,检查更新的文件*/
gi=GeoIP_open(“/usr/share/GeoIP/GeoIP.dat”,
GEOIP_标准(GEOIP_检查_缓存);
}否则{
/*从内存读取,速度更快,但占用更多内存*/
gi=GeoIP\u open(“/usr/share/GeoIP/GeoIP.dat”,GeoIP\u MEMORY\u CACHE);
}
if(gi==NULL){
fprintf(stderr,“打开数据库时出错\n”);
出口(1);
}
/*确保GeoIP能够优雅地处理无效查询*/
returnedCountry=GeoIP\u country\u code\u by\u addr(gi,NULL);
if(returnedCountry!=NULL){
fprintf(标准,
无效的查询测试失败,得到非NULL,应为NULL\n“;
失败=1;
}
returnedCountry=GeoIP\u country\u code\u by\u name(gi,NULL);
if(returnedCountry!=NULL){
fprintf(标准,
无效的查询测试失败,得到非NULL,应为NULL\n“;
失败=1;
}
f=fopen(“/home/aa/test/country_test.txt”,“r”);
而(fscanf(f,“%s%s%s”,IP地址,expectedCountry,expectedCountry3)
!=EOF){
returnedCountry=GeoIP\u country\u code\u by\u addr(gi,IP地址);
if(returnedCountry==NULL
||strcmp(返回国家/地区、预期国家/地区)!=0){
fprintf(标准,
“为%s测试地址%d失败,得到%s,预期为%s\n”,
测试编号、IP地址、返回的国家/地区、预期的国家/地区);
失败=1;
}
returnedCountry=GeoIP\u country\u code\u by\u name(gi,IP地址);
if(returnedCountry==NULL
||strcmp(返回国家/地区、预期国家/地区)!=0){
fprintf(标准,
“测试名称%d(用于%s)失败,获得%s,预期为%s\n”,
测试编号、IP地址、返回的国家/地区、预期的国家/地区);
失败=1;
}
returnedCountry=GeoIP\u country\u code3\u by\u addr(gi,IP地址);
if(returnedCountry==NULL
||strcmp(返回国家/地区,预期国家/地区3)!=0){
fprintf(标准,
“为%s测试地址%d失败,得到%s,预期为%s\n”,
测试编号、IP地址、返回的国家/地区、预期的国家/地区);
失败=1;
}
returnedCountry=GeoIP\u country\u code3\u by\u name(gi,IP地址);
if(returnedCountry==NULL
||strcmp(返回国家/地区,预期国家/地区3)!=0){
fprintf(标准,
“测试名称%d(用于%s)失败,获得%s,预期为%s\n”,
测试编号、IP地址、返回的国家/地区、预期的国家/地区);
失败=1;
}
test_num++;
}
fclose(f);
f=fopen(“/home/aa/test/country_test2.txt”,“r”);
while(fscanf(f,“%s%s”,IP地址,预期国家)!=EOF){
returnedCountry=GeoIP\u country\u code\u by\u addr(gi,IP地址);
if(returnedCountry==NULL
||strcmp(返回国家/地区、预期国家/地区)!=0){
fprintf(标准,“测试地址%d%s失败,获得%s,预期为%s\n”,
测试编号、IP地址、返回的国家/地区、预期的国家/地区);
失败=1;
}
test_num++;
}
fclose(f);
f=fopen(“/home/aa/test/country_test_name.txt”,“r”);
while(fscanf(f,“%s%s”,IP地址,预期国家)!=EOF){
returnedCountry=GeoIP\u country\u code\u by\u name(gi,IP地址);
if(returnedCountry==NULL
||strcmp(返回国家/地区、预期国家/地区)!=0){
fprintf(标准,“测试地址%d%s失败,获得%s,预期为%s\n”,
测试编号、IP地址、返回的国家/地区、预期的国家/地区);
失败=1;
}
test_num++;
}
fclose(f);
GeoIP_删除(gi);
}
返回失败;
}
谢谢将
-g
添加到编译命令行,然后您就可以自由使用gdb./a.out
或valgrind./a.out
(这里
/a.out
是您的程序名)将-g
添加到编译命令行,然后您可以自由使用gdb./a.out
或valgrind./a.out
(这里
/a.out
是您的程序名)正如许多人所说:使用调试器或类似valgrind
的工具
然而,这肯定是问题的根源(我已经剥离了不感兴趣的部分):
有几个这样的例子。您也有不检查返回值的
fopen
调用。总是这样做。正如许多人所说:使用调试器或类似valgrind
的工具
然而,这肯定是问题的根源(我已经剥离了不感兴趣的部分):
有几个这样的例子。您也有不检查返回值的
fopen
调用。总是这样做。用于此。您是否尝试过通过gdb之类的调试器运行程序?当然,使用-g编译,然后使用调试器运行(gdb myprogram
)是的,有,在调试器中运行它。快速猜测:一些fopen()
调用失败,返回一个NUL
if (returnedCountry == NULL || ...) {
fprintf(stderr, ".. %s ..\n", returnedCountry...);
...
}