malloc和strcpy,illegall通路,C
关于这一点我读了很多书,但我找不到错误 我有一个过程来说明是否在另一个较长的CSV字符串中找到了字符串值(在下面的代码中,inIP是IPv4地址,allow_hosts应该是IPv4地址的CSV列表,但它应该适用于任何字符串和CSV字符串列表) 代码如下:malloc和strcpy,illegall通路,C,c,memory,C,Memory,关于这一点我读了很多书,但我找不到错误 我有一个过程来说明是否在另一个较长的CSV字符串中找到了字符串值(在下面的代码中,inIP是IPv4地址,allow_hosts应该是IPv4地址的CSV列表,但它应该适用于任何字符串和CSV字符串列表) 代码如下: bool stringFound(char* inIP,char* allow_hosts){ bool found=false; int i =0; int j =0; char* ip; printf("strlen(allow_host
bool stringFound(char* inIP,char* allow_hosts){
bool found=false;
int i =0;
int j =0;
char* ip;
printf("strlen(allow_hosts)=%d\n",strlen(allow_hosts));
while(i<strlen(allow_hosts) && !found){
j=i;
while(allow_hosts[i]!=',' && i<strlen(allow_hosts)){
i++;
}
printf("jota = %d\n",j);
printf("i = %d\n",i);
printf("i-j+1 = %d\n",i-j+1);
ip = malloc(i-j+1);//1 more for '\0'
strncpy(ip,allow_hosts+j,i);//line 25, illegal access, problem one
printf("it copies=%s\n",ip);
ip[i-j]='\0';
found = strcmp(ip,inIP)==0;
//free(ip);//Problem two
if(found)
return found;
i++;
}
return found;
};
据我所知,malloc有问题,但是当我用
stringFound("8.8.7.8","127.0.0.1,8.8.8.8");
stringFound("8.8.54.8","127.0.0.1,8.8.8.8,192.168.92.3");
它正在印刷
jota = 10
i = 17
i-j+1 = 8
it copies=8.8.8.8
strlen(allow_hosts)=30
jota = 0
i = 9
i-j+1 = 10
//the error I showed above appears here
我还用Valgrind对其进行了测试,称之为Valgrind./myProgram,它说:
==3406== Invalid write of size 1
==3406== at 0x402D763: strncpy (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3406== by 0x80485EB: stringFound (esta.c:25)
==3406== by 0x80486CC: test (esta.c:49)
==3406== by 0x8048803: main (esta.c:75)
==3406== Address 0x41fe0f0 is 0 bytes after a block of size 8 alloc'd
“test”是多次调用我的过程的函数,第25行在代码中标记为“problem here”
正如您所看到的,我在free()行中有一条注释。如果使用此行,错误将更改为
Error in `./esta': free(): invalid next size (fast): 0x09d11008
Aborted (core dumped)
我认为这两个错误是由相同的原因造成的,但我没有发现错误
strncpy(ip,allow_hosts+j,i);//line 25, illegal access, problem one
是的,这应该会导致问题。我认为第三个参数应该是I-j
,而不是I
,你应该写:
strncpy(ip,allow_hosts+j,i-j);
在循环的任何下一次迭代中,i
都会变大,但您只能为从j开始的ip字符串分配空间,因此您也只能复制该部分
strncpy(ip,allow_hosts+j,i);
这里的问题是需要片段的长度作为第三个参数,但要传递结束位置。您应该通过i-j
2个问题:
ip = malloc(i-j+1);
// Wrong limit on strncpy
// strncpy(ip,allow_hosts+j,i);
strncpy(ip,allow_hosts+j,i-j);
// ip may not be null character terminated, re-arrange code
ip[i-j]='\0';
printf("it copies=%s\n",ip);
// ip[i-j]='\0';
free()
问题可能是由于上述问题已损坏
更微妙的问题:strlen返回的长度是type
size\t
。如果size\u t
和int
的大小相似,这个问题可能不会很快表现出来最好不要指望这一点,而是使用size\u t
size_t i =0;
size_t j =0;
// Change format specifier too.
printf("strlen(allow_hosts)=%zu\n",strlen(allow_hosts));
printf("jota = %zu",j); // Review all printf formats
- strstr()是一个可用的库函数
- 你不需要去马洛克;检查一下字符串
- 如果找到,该字符串可以是较大的有效虚线四元字符串的部分
- (注意:strncpy()是一个非常糟糕的函数,几乎不需要)
#包括
#包括
int stringFound(char*inIP,char*allow_主机){
char*cp;
cp=strstr(允许主机,inIP);
/*如果找到子字符串:
**检查它是否是较大虚线四元字符串的一部分
*/
如果(!cp)返回0;
如果(cp>allow_hosts&&cp[-1]>='0'&&cp[-1]='0'&&cp
size_t i =0;
size_t j =0;
// Change format specifier too.
printf("strlen(allow_hosts)=%zu\n",strlen(allow_hosts));
printf("jota = %zu",j); // Review all printf formats
#include <stdio.h>
#include <string.h>
int stringFound(char *inIP, char *allow_hosts){
char *cp;
cp = strstr(allow_hosts, inIP);
/* IF substring is found:
** check if it is PART of a LARGER dotted quad string
*/
if (!cp) return 0;
if (cp > allow_hosts && cp[-1] >= '0' && cp[-1] <= '9' ) return 0;
cp += strlen(inIP); if (*cp >= '0' && *cp <= '9' ) return 0;
return 1;
}
int main(int argc, char **argv)
{
int found;
char *the_ip = "1.2.3.4";
char *should_fail = "5.2.3.4 ,1.2.3.45, 11.2.3.4, 1.2.3.4.";
char *should_match = "5.2.3.4 ,6.2.3.4, 1.2.3.4, 9.2.3.4";
found = stringFound(the_ip, should_fail);
printf("(should fail) Found=%d\n" , found);
found = stringFound(the_ip, should_match);
printf("(should match) Found=%d\n" , found);
return 0;
}