malloc和strcpy,illegall通路,C

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

关于这一点我读了很多书,但我找不到错误

我有一个过程来说明是否在另一个较长的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_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;
}