2012-04-27 134 views
2

我试图从名为urlTokener的函数返回数据结构,其中数据结构中的一个成员是char*类型的数组,另一个是int。当我在函数urltokener中打印数组的值时,我得到了正确的类型,但是我发现在使用返回数据结构的主函数中,数组不包含正确的值,因为输出不正确(与函数中的不一样)。看来这个函数没有正确地返回数据结构。你能否在下面的代码中检查并说出我做错了什么?返回返回数据结构的错误,返回数组类型char *

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

struct tokenDetail 
{ 
    char* theArray[256]; 

    int sizeOfArray; 
}; 


tokenDetail urlTokener(const char *,char*); 

void main() 
{ 
    // String to be splitted. 
    const char* url="/v1/AUTH_abb52a71-fc76-489b-b56b-732b66bf50b1/images?limit=1000&delimiter=/&format=xml" ; 

    tokenDetail newdetails; 
    newdetails=urlTokener(url,"?"); 
    for (int i=0;i<newdetails.sizeOfArray;i++) 
    { 
     printf("This is in main where size is %d and the value %s\n",newdetails.sizeOfArray,newdetails.theArray[i]); 
    } 
} 

tokenDetail urlTokener(const char* urlLine,char* delimiter) 
{ 
    char urlArray[256]; 
    strncpy(urlArray, urlLine, sizeof(urlArray)); 
    tokenDetail details; 
    unsigned int index = 0; 
    details.theArray[index] = strtok(urlArray, delimiter); 

    while(details.theArray[index] != 0) 
    { 
     printf("This is in function %s\n",details.theArray[index]); 
     ++index; 
     details.theArray[index] = strtok(0, delimiter); 
    } 
    for (int i=0;i<index;i++) 
    { 
     printf("This is in function 2nd time %s\n",details.theArray[i]); 
    } 
    details.sizeOfArray=index; 
    return details; 
} 

请注意:我这样做是为了C++,但我不能(通过谁给我这个任务的人)使用命名空间std和库字符串。这就是为什么代码与C类似的原因。由于这个限制,我很困惑是否将它标记为C或C++。所以我用c和C++标记了它。也许你可以自己决定。

+0

难道说'urlArray'是一个堆栈变量? 'details.theArray'中的指针指向'urlArray'中的地址,从函数返回后无效。 – 2012-04-27 09:49:19

+0

我还没有详细阅读,但大量使用'printf','strtok'和类似的语句暗示这是c,所以Luchian Grigore关于copy ctor和赋值运算符的回答是不相关的。你能否澄清你是否想要c或C++,并根据需要更改标签。 – BoBTFish 2012-04-27 09:49:36

+0

我正在做一个更大的项目的测试,这个项目必须用C++完成,但是我不能使用命名空间Std和字符串库。我只能使用cstring或string.h和stdio.h。所以,这确实是C++,但我不得不使用类似于c的许多东西。我希望能消除你的困惑。 @ Bobtfish – 2012-04-27 09:56:24

回答

3

你填充指针数组从strtok,这反过来 是指针到您的urlArray,局部变量,它不再 存在,一旦你从函数返回返回。

这是C还是C++?您已经设置了两个标签,并且解决方案 不同。在C++中,显而易见的解决方案是用std::string替换 tokenDetail中的char*。在C中,这有点复杂。 您已经在您的结构中动态分配字符串(使用 非标准但广泛可用的strdup),并要求客户端使用 释放它们。这里通常的解决方案是返回指向 动态分配的指针TokenDetailfreeTokenDetail函数 ,客户端需要调用返回的指针。这 给你完全的自由,你如何做你的分配和释放。 (该 通常的解决办法是,事实上,只提供 TokenDetail向客户预先声明,并提供他们有 来电访问它的元素的功能。)

0

您没有实现复制构造函数,析构函数或赋值运算符。

因为你的价值回报,拷贝构造函数被调用的return details;,但是默认的一个只做一个浅拷贝,因此该领域char* theArray[256];没有正确复制。

+0

如果是C++,唯一正确的答案是使用'std :: string'(在这种情况下,默认的拷贝构造函数等会很好)。如果代码使用C语言,则不能使用复制构造函数等。 – 2012-04-27 10:10:58

+0

@JamesKanze它是C++,op在评论中提到它,我编辑了这个问题。你是对的,使用std :: string是要走的路。 +1 – 2012-04-27 10:12:28

2

这里的问题不是tokenDetail需要任何手写拷贝构造函数,析构函数或赋值运算符,但它不需要。问题在于,当您离开urlTokener()时,本地变量urlArray被销毁,因此details.theArray元素指向的位置变为无效。而且,当然,返回的tokenDetail也是如此,这是它的副本。