2014-11-24 140 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

相关问题