memcpy 在 strstr 成功后导致段错误

memcpy causes segfault after strstr succeeds

我试图制作一个函数,将任何 URL 作为输入并从中删除 http://,然后从 URL 的其余部分获取 uri 和域。当我执行下面的代码时,我在 memcpy 语句处收到一个分段错误,标记为“//此处出现段错误”。

执行后,我收到以下输出:

TEST
http:// found
Segmentation fault

我预期如下:

TEST
http:// found
/ found
www.x.com /a/b/c

当我声明一个大缓冲区 space 以将结果复制到其中时,为什么会收到分段错误?我的程序中是否有什么东西导致指向结果的指针无效?

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void getdomurl(const char* in,char* uri,char* dom){
    char b[200000],*p=strstr(in,"http://");
    if (p){
        printf("http:// found\n");
        memcpy(b,p+7,100000); //seg fault here
    }else{
        printf("http:// not found\n");
        memcpy(b,in,100000);
    }
    printf("/ scan\n");
    p=strstr(b,"/");
    if (p){
        printf("/ found\n");
        memcpy(dom,b,p-b);memcpy(uri,p,100000);
    }else{
        printf("/ not found\n");
        memcpy(dom,b,100000);uri[0]='/';uri[1]='[=12=]';
    }
}

int main(int argc,char* argv[]){
char uri[100000];char dom[10000];
printf("TEST\n");
getdomurl("http://www.x.com/a/b/c",uri,dom);
printf("%s %s",uri,dom);
return 0;
}

pin 中分配了一个位置,其中包含的字符串文字比您要求 memcpy 从中复制的 100000 字节短得多。

虽然你已经明确为数组b分配了足够的内存,但你输入的字符串可能没有100,000字节。解决此问题的方法是使用一个查找空终止字符的函数 strmcpy,而不是 memcpy。 http://www.cplusplus.com/reference/cstring/strncpy/

strncpy(b,p+7,200000);

同时替换 memcpy 的其他 3 个用途。

确实不需要memcpy(),因为整个工作都可以用指针完成。这是我为自己的 fetch 实用程序制作的粗略草图:

#include <stdio.h>
#include <string.h>
void parseurl(char *argv)
{
    char *host;
    char *type;
    char *page;

    type = host = page = argv;
    if ( (host = strstr(argv, "://")))
    {
        *host = '[=10=]';
        host += 3;
    }
    else    
        return;
    if ((page = strstr(host, "/")))
        *page++ = '[=10=]';

    printf("Attempting an [%s] protocol on [%s] to retrieve [%s]\n", type, host, page);
    /* fetch(type, host, page); */
    return;
}

/* "driver" */
int main(int argc, char *argv[])
{ 
    if ( argc != 2 )
        return 1;
    parseurl(*++argv);
    return 0;
}

可以运行如下:

./parseurl http://www.google.com/index.html