以下代码中的分段故障11。如何避免溢出? void main(int-argc,char*argv[]){ char*hostname=(char*)malloc(sizeof(char)*1024); 主机名=getClientHostName(“122.205.26.34”); printf(“%s\n”,主机名); 免费(主机名); } char*getClientHostName(char*client_ip){ char主机名[5][2]; 主机名[0][0]=“122.205.26.34”; 主机名[0][1]=“aaaaa”; 主机名[1][0]=“120.205.36.30”; 主机名[1][1]=“BBB”; 主机名[2][0]=“120.205.16.36”; 主机名[2][1]=“ccccc”; 主机名[3][0]=“149.205.36.46”; 主机名[3][1]=“dddddd”; 主机名[4][0]=“169.205.36.33”; 主机名[4][1]=“EEEE”; 对于(int i=0;i
将以下代码中的分段故障11。如何避免溢出? void main(int-argc,char*argv[]){ char*hostname=(char*)malloc(sizeof(char)*1024); 主机名=getClientHostName(“122.205.26.34”); printf(“%s\n”,主机名); 免费(主机名); } char*getClientHostName(char*client_ip){ char主机名[5][2]; 主机名[0][0]=“122.205.26.34”; 主机名[0][1]=“aaaaa”; 主机名[1][0]=“120.205.36.30”; 主机名[1][1]=“BBB”; 主机名[2][0]=“120.205.16.36”; 主机名[2][1]=“ccccc”; 主机名[3][0]=“149.205.36.46”; 主机名[3][1]=“dddddd”; 主机名[4][0]=“169.205.36.33”; 主机名[4][1]=“EEEE”; 对于(int i=0;i,c,C,将*添加到类型定义char*主机名[5][2]。这必须是指针数组,而不是简单的chars。另一个必要的更改是strcpy而不是strcpy(主机名,getClientHostName(“122.205.26.34”); PS:始终尝试使用0个编译器警告进行编译,而不仅仅是0个错误!修复编译器错误和警告后,您会得到: void main(int argc, char* argv[]) { char* hostname = (char*)malloc(sizeof(char)*1024);
*
添加到类型定义char*主机名[5][2]
。这必须是指针数组,而不是简单的char
s。另一个必要的更改是strcpy
而不是strcpy(主机名,getClientHostName(“122.205.26.34”);
PS:始终尝试使用0个编译器警告进行编译,而不仅仅是0个错误!修复编译器错误和警告后,您会得到:
void main(int argc, char* argv[]) {
char* hostname = (char*)malloc(sizeof(char)*1024);
hostname = getClientHostName("122.205.26.34");
printf("%s\n", hostname);
free(hostname);
}
char* getClientHostName(char* client_ip) {
char hostnames[5][2];
hostnames[0][0] = "122.205.26.34";
hostnames[0][1] = "aaaaa";
hostnames[1][0] = "120.205.36.30";
hostnames[1][1] = "bbbbb";
hostnames[2][0] = "120.205.16.36";
hostnames[2][1] = "ccccc";
hostnames[3][0] = "149.205.36.46";
hostnames[3][1] = "dddddd";
hostnames[4][0] = "169.205.36.33";
hostnames[4][1] = "eeeeee";
for(int i = 0; i<5; i++) {
if(!strcmp(hostnames[i][0], client_ip))
return (char*)hostnames[i][1];
}
return NULL;
}
const char*getClientHostName(const char*client_ip){
const char*主机名[5][2];
主机名[0][0]=“122.205.26.34”;
主机名[0][1]=“aaaaa”;
主机名[1][0]=“120.205.36.30”;
主机名[1][1]=“BBB”;
主机名[2][0]=“120.205.16.36”;
主机名[2][1]=“ccccc”;
主机名[3][0]=“149.205.36.46”;
主机名[3][1]=“dddddd”;
主机名[4][0]=“169.205.36.33”;
主机名[4][1]=“EEEE”;
对于(int i=0;i
有没有更好的方法,我不必硬编码尺寸
养成使用所有警告和调试信息编译的习惯:gcc-Wall-Wextra-g
with。改进代码以完全不获取警告
如果您想获得真正的IP地址,这是特定于操作系统的(因为standard不知道IP地址,请通过阅读进行检查)。在Linux上,您可以使用名称服务例程,如&)或过时的
如果这只是一个与TCP/IP套接字没有实际关系的练习(请参阅),则可以将表存储在某个全局数组中:
然后定义一个包含它们的数组,并使用一些{NULL,NULL}
条目终止它:
struct myipentry_st {
const char* myip_hostname;
const char* myip_address;
};
您最好有一个全局or(而不是一个坐在桌面上),因为您不想在每次调用getClientHostName
时都填充它
那么您的查找例程(效率低下,因为在线性时间内)将是:
const struct myipentry_st mytable[] = {
{"aaaaa", "122.205.26.34"},
{"bbbb", "120.205.36.30"},
/// etc
{NULL, NULL} // end marker
};
您甚至可以将该表声明为指针:
然后使用calloc
分配它,并从某个文本文件中读取它的数据
阅读您正在使用的每个或外部函数的文档。不要忘记检查失败(例如,calloc
,如)。通过适当调用free
避免。使用调试器gdb
和。小心
在现实世界中,您可能会有数千个条目,并且会执行多次查找(可能是数百万次,例如,web服务器或客户端中的每个请求一次)。然后选择一个更好的(或者可能).读一些。你的代码不应该编译得很干净。使用gcc-Wall-Wextra-g
编译它,谢谢你的输入。但问题是,我肯定可以实现更好的方法,我可以做到。但不是用C。这是我第一次用C编写代码。第一次。就像,第一次。我有一周的时间来做这件事所以我没有足够的时间来学习C。我对Java和某种程度上的Python比较熟悉,但是C非常不同。所以现在我只是想让它以某种方式工作。
const struct myipentry_st mytable[] = {
{"aaaaa", "122.205.26.34"},
{"bbbb", "120.205.36.30"},
/// etc
{NULL, NULL} // end marker
};
const char* getClientHostName(char* client_ip) {
for (const struct myipentry_st* ent = mytable;
ent->myip_hostname != NULL;
ent++)
// the if below is the only statement of the body of `for` loop
if (!strcmp(ent->myip_address, client_ip))
return ent->myip_hostname;
// this happens after the `for` when nothing was found
return NULL;
}
const struct myipentry_st**mytable;