C中的Seg故障(相同的逻辑在另一个程序中工作)
我有一个虚拟字符数组,它有3个URL信息C中的Seg故障(相同的逻辑在另一个程序中工作),c,sockets,segmentation-fault,C,Sockets,Segmentation Fault,我有一个虚拟字符数组,它有3个URL信息 char *A[] = {"opc.tcp://localhost:4840", "opc.tcp://helloworld:4840", "opc.tcp://helloworldagain:4844"}; char *B[] = {}; char *C[] ={}; int size = sizeof(A)/sizeof(A[0]); 以上部分只是一个虚拟复制示例 for(size_t i
char *A[] = {"opc.tcp://localhost:4840", "opc.tcp://helloworld:4840", "opc.tcp://helloworldagain:4844"};
char *B[] = {};
char *C[] ={};
int size = sizeof(A)/sizeof(A[0]);
以上部分只是一个虚拟复制示例
for(size_t i = 0; i < serverOnNetworkSize; i++) {
UA_ServerOnNetwork *server = &serverOnNetwork[i];
A[i] = (char *)UA_malloc(server->discoveryUrl.length+1);
memcpy(A[i],server->discoveryUrl.data,server->discoveryUrl.length);
A[i][server->discoveryUrl.length] = 0;
for(大小i=0;i发现URL.length+1);
memcpy(A[i],服务器->发现URL.data,服务器->发现URL.length);
A[i][server->discoveryUrl.length]=0;
这就是[]如何准确地获取URL信息。然而,整个程序在我的系统中运行顺利,但在docker上无法运行。我尝试通过硬编码URL的
我需要分别提取主机名和端口号,并将其传递给一些自定义函数
for(int i=0;i<size;i++){
int length = strlen(A[i]);
B[i] = A[i] + 10;
printf("Hostname without AA binding : %s\n", B[i]); // removes the initial binding (opc.tcp://)
char *p = strrchr(B[i], ':');
int port = strtoul(p+1, NULL, 10);
printf("Extracted port : %d\n",port); // I get port information
printf("Original A[i] = %s\n",A[i]);
A[i][length-5]='\0'; //Here it fails.
printf("A[i] [length - 5] : next line =%s\n",A[i]); // I expect:opc:tcp//localhost
//without initial tcp binding
C[i] = A[i] + 10;
printf("Hostname after removing binding : %s\n", C[i]); //expect: localhost
if(i!=0){
char ip_address[50];
find_ip_address(C[i],ip_address);
socketCommunication(ip_address,C[i],port);///,&B[i]);
}
}
for(int i=0;ih地址列表;
for(count=0;ipaddress[count]!=NULL;count++)
{
strcpy(ip_地址,inet_ntoa(*ipaddress[count]);
返回0;
}
}
返回1;
}
void socketCommunication(字符*ip_地址,字符*主机名,int端口){
int clientSocket,ret;
serverAddr中的结构sockaddr\u;
字符缓冲区[1024];
clientSocket=socket(AF\u INET,SOCK\u STREAM,0);
如果(clientSocket您试图更改导致segfault的常量字符串文字。
您需要将A声明为2d数组(charA[][SIZE]
)或使用动态内存分配
代码还有其他问题:
- 未分配B和C,这可能导致运行时错误
B[i]=A[i]+10;
不可读且容易混淆,最好使用指针
您缺少一些可能相关的代码。您能发布for循环的其余部分,以及socketCommunication和find_ip_address的定义吗?@Ray,它说post的代码太多,无法发布。因此find_ip_address基本上将主机名转换为ip地址。socketCommunication将尝试连接到这些ip地址nd端口信息您的B和C数组的长度为0,因此使用derefence B[i]或C[i]是未定义的行为。未定义的行为本身就是一种神秘的方式。不值得怀疑为什么“执行之前的所有内容”。根据堆栈布局,对B[i]的任何赋值
可以破坏A
的内容。未定义的行为不必立即崩溃。它可以隐藏并等待,直到你不再期待它。但除此之外,它崩溃的原因很可能是A[i][length-5]='\0'
是字符串文字所在的只读内存。您好@saeedkazemi,请查看我的编辑内容好吗?@RakshanPremsagarKapikad我不确定您的程序中实际使用了哪个代码块。分段错误可能是由不同的问题引起的,例如,如果[I]的长度小于5,那么[I][length-5]可能会导致segfault。可能内存分配失败并返回NULL(尽管可能不是)。提供的代码不够充分和清晰,无法进行解释。我建议将代码上载到某个位置,并在此处发布链接。“a的元素大小不一定相等”…这就是你错的地方。根据定义,数组的元素大小都相同。本例中的元素是指针。@mlp你是对的,修复了。
int find_ip_address(char *hostname, char *ip_address)
{
struct hostent *host_name;
struct in_addr **ipaddress;
int count;
if((host_name = gethostbyname(hostname)) == NULL)
{
herror("\nIP Address Not Found\n");
return 1;
}
else
{
ipaddress = (struct in_addr **) host_name->h_addr_list;
for(count = 0; ipaddress[count] != NULL; count++)
{
strcpy(ip_address, inet_ntoa(*ipaddress[count]));
return 0;
}
}
return 1;
}
void socketCommunication(char *ip_address,char *hostname, int port){
int clientSocket,ret;
struct sockaddr_in serverAddr;
char buffer[1024];
clientSocket = socket(AF_INET,SOCK_STREAM,0);
if(clientSocket<0){
printf("Error in connection \n");
exit(1);
}
memset(&serverAddr,'\0',sizeof(serverAddr));
serverAddr.sin_port = htons(port);
serverAddr.sin_family=AF_INET;
serverAddr.sin_addr.s_addr=inet_addr(ip_address);
ret = connect(clientSocket,(struct sockaddr*)&serverAddr,sizeof(serverAddr));
if(ret<0){
printf("Error");
}