2014-11-24 109 views
-2

我有一個字符串,爲此我分配內存。之後,我將這個字符串傳遞給另一個函數,然後從第二個函數傳遞給第三個函數。問題是,在tird函數完成後,我可以訪問/使用變量。但在第二個函數完成後,我無法在第一個函數中訪問它的值。所以顯然我做錯事,但我不是什麼。 有人可以幫我嗎? 當然,如果任何人有更好的想法,我該如何做我想做的,我也會很感激。 我的代碼到目前爲止:什麼是分配和傳遞字符串的正確方法?

#define MAX_SIZE 100 

void Func1() 
{ 
    char *Test = NULL; 
    Test = (char *)malloc(MAX_SIZE*sizeof(char)); 
    if (Test == NULL) 
    { 
     return; 
    } 

    Func2(Test); 

    if (Test!= NULL) free(Test); 
} 

void Func2(char *string) 
{ 
    Func3(&string); 
} 

void Func3(char **string) 
{ 
    if (Len > MAX_SZIE) 
    { 
     char *tmp = NULL; 
     tmp = (char *)realloc(*string, Len + 1); 
     if (!tmp) 
     { 
       return; 
     } 
     *string = tmp; 
     memset(*string, 0, sizeof(*string)); 
    } 
    memcpy(*string, SomeOtherString, Len); 
    free(SomeOtherString); 
} 

在此先感謝!

更新: 更新的功能,與目前的代碼,我現在:

bool __stdcall Function(DataToSendBack *DataArray) 
{ 
char *Result = NULL; 
char InString[ MAX_SIZE ] = { 0 }; 
int DataLen = 0; 
bool bRetVal = false; 

__try 
{ 
    Result = (char *)malloc(MAX_SIZE); 
    if (Result == NULL) 
    { 
     __leave; 
    } 

    memset(InString, 0, sizeof(InString)); 
    memset(Result, 0, sizeof(Result)); 

    memcpy(InString, DataArray->StringIn, strlen(DataArray->StringIn)); 

    Result = GetInfo(InString, Result, &DataLen); 
    if (Result == NULL) 
      { 
     MessageBoxA(NULL,"error",NULL,NULL); 
        __leave; 
      } 

    if (strlen(ErrorMsg) > 0) strcpy(DataArray->ErrorMessage, ErrorMsg); 

    if (DataArray->RequiredSize < DataLen) 
    { 
     DataArray->RequiredSize = DataLen; 
     strcpy(DataArray->ErrorMessage, ErrorMsg); 
     __leave; 
    } 

    DataArray->Result = _strdup(Result); 
    bRetVal = true; 
} 
__finally 
{ 
    if (Result != NULL) free(Result); 
} 

return bRetVal; 

} 

char * GetInfo(char *String, char *Result, int *DataLen) 
{ 
    bool bRetVal = false; 

__try 
{ 
    if (DoStuff(String, &Result, DataLen)) 
    { 
     bRetVal = true; 
    } 
} 
__finally 
{ 
    // free other things 
} 

return Result; 
} 

bool DoStuff(char *MyString, char **Result, int *DataLen) 
{ 
__try 
{ 
    //Call function which returns dwsize 
    *DataLen = dwSize * 2; 
      OtherString = SomFunction(); 
    if (strlen(OtherString) > MAX_SIZE) 
    { 
     char *tmp = NULL; 
     tmp = (char *)realloc(*Result, strlen(OtherString)); 
     if (!tmp) 
     { 
      __leave; 
     } 
     *Result = tmp; 
     memset(*Result, 0, sizeof(*Result)); 
    } 

    memcpy(*Result, OtherString, strlen(OtherString)); 

    free(OtherString); 

    bretVal = true; 
} 
__finally 
{ 
    // free other things 
} 

return bretVal; 
} 
+0

不要在C中投入'malloc'。 – crashmstr 2014-11-24 20:43:36

+1

'if(Result == NULL)'...其中是'Result'聲明? – abelenky 2014-11-24 20:43:38

+0

對不起,效果測試。 – kampi 2014-11-24 20:44:19

回答

2

Func3()修改Func1()分配的指針。你需要傳遞迴FUNC1():

void Func1() 
{ 
    char *Test = NULL; 
    if (NULL == (Test = malloc(MAX_SIZE)) { 
     // Handle case of OOM error 
     return; 
    } 

    // Func2 may modify Test 
    Test = Func2(Test); 

    if (NULL == Test) { 
     // Handle case of error in Func3 
    } 
    free(Test); // Test = NULL; 
} 

/** 
* Reads and modifies (through a call to Func3) a pointer to string 
*/ 
char * Func2(char *string) 
{ 
    Func3(&string); 
    return string; 
} 

此外,在FUNC3(),您需要:

memset(*string, 0, Len + 1); 

零整個字符串。

但是實際上你正在將OtherString寫入*string,因此如WhozCraig指出的那樣對所有這些字節進行置零是不必要的。什麼你應該做的是確保你有足夠的空間,字符串後,立即零一個字節如果是必要的。所以這將是

strncpy(*string, OtherString, Len); 
(*string)[Len] = 0x0; 

或更有效(因爲strncpy將零OtherString的拷貝後的任何到來的時候,最多len個字節)

size_t new_len = strlen(OtherString); 
if (new_len <= Len) { 
    // Copy, including last zero 
    memcpy(*string, OtherString, new_len+1); 
} else { 
    // Copy Len bytes, from 0 to Len-1 
    memcpy(*string, OtherString, Len); 
    // Zero last byte to make it a valid C string 
    (*string)[Len] = 0x0; 
} 

或 爲size_t new_len =分鐘(LEN,strlen的( OtherString)); memcpy(* string,OtherString,new_len); //將最後一個字節清零以使其成爲有效的C字符串 (* string)[new_len] = 0x0;

更新

出於測試目的,這是FUNC3()我使用:

#define OtherString  "To be or not to be, that is the question\n" 
#define Len    10240 
#define min(a,b)  (((a)<(b))?(a):(b)) 

void Func3(char **string) 
{ 
    char *tmp = realloc(*string, Len+1); 
    if (NULL == tmp) 
    { 
      return; 
    } 
    *string = tmp; 
    size_t new_len = strlen(OtherString); 
    new_len  = min(Len, new_len); 
    memcpy(*string, OtherString, new_len); 
    // Zero last byte to make it a valid C string 
    (*string)[new_len] = 0x0; 
} 

在一種情況下,它返回「是或不是」,在其它(長度= 16 )如預期的那樣它返回「待定或不到」。

+1

關於後者'memset',只有其中一個很重要時,用'0'填充'Len + 1'槽是沒有意義的;最後一個''(* string)[Len ] = 0;'memcpy'就足夠了 – WhozCraig 2014-11-24 21:11:46

+0

好的,我會修改我的答案 – LSerni 2014-11-24 21:31:21

+0

所以剛剛編輯過,那個Func2應該返回一個char *,對不對?不幸的是我收到以下錯誤: 「圍繞變量'Test'的棧被損壞了」 – kampi 2014-11-24 21:35:49

0

realloc()阿婷在字符串中Func3()。但是,新的可能修改的指針永遠不會返回到Func1(),因爲Func2()會按值而不是按指針獲取指針。因此,您將訪問一個潛在的釋放內存區域。

解決方案:根據您的需要,您可能需要將指針傳遞給Func2()(也可能是Func1())以傳遞原始字符串。

+0

你可能請改正我的代碼?我不能使它工作:( – kampi 2014-11-24 21:00:54

相關問題