我有一个字符串,我为此分配内存。之后,我将此字符串传递给另一个函数,然后从第二个函数将其传递给第三个函数。问题是,在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 :(得分: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 = min(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;
}
在一种情况下,它返回&#34;要成为或不成为&#34;,在另一个中(Len = 16)它返回&#34;成为或不成为&#34;,如预期的那样。< / p>
答案 1 :(得分:0)
您realloc()
点击Func3()
中的字符串Func1()
。但是,新的,可能修改的指针永远不会返回到Func2()
,因为Func2()
按指针获取指针,而不是指针。因此,您将访问可能已释放的内存区域。
解决方案:根据您的需要,您可能希望通过指针将原始字符串传递给Func1()
(也可能传递给{{1}})。