2012-04-27 131 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也是如此,這是它的副本。