在strstr成功后,memcpy会导致段错误

时间:2015-10-12 23:09:48

标签: c pointers segmentation-fault buffer

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

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

TEST
http:// found
Segmentation fault

我期待以下内容:

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

当我声明一个大的缓冲区空间来复制结果时,为什么会收到分段错误?我的程序中是否存在导致结果无效指针的内容?

以下是代码:

#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]='\0';
    }
}

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;
}

3 个答案:

答案 0 :(得分:2)

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

strncpy(b,p+7,200000);

也替换了memcpy的其他3种用途。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

实际上不需要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 = '\0';
        host += 3;
    }
    else    
        return;
    if ((page = strstr(host, "/")))
        *page++ = '\0';

    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