首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ Builder >

请问一个功能多谢

2012-03-14 
请教一个功能谢谢。void__fastcallswapstr(char*c,char*c1){c1c}void__fastcalltfform1::Button1Click(To

请教一个功能谢谢。
void   __fastcall   swapstr(char   *c,char   *c1)
{
    c1=c;
}

void   __fastcall   tfform1::Button1Click(Tobject   *sender)
{
      AnsiString   str= "sssss ";
      Ansistring   str= " ";
      swapstr(str.c_str(),str1.c_str());

      ShowMessage(str1);
   
}

为什么str1的值没有改变?我应该怎么做?
swap函数的两个参数的char类型是不能变的。我只是自己写了一个小例子,具体是在写dll用的

[解决办法]
~!~


Don 't store the result of AnsiString::c_str()
Examine the following code segment.

AnsiString strText = "Howdy Mr. Ditka. ";

char *ptr = strText.c_str();

strText = "Goodbye Mr. Ditka ";

Label1-> Caption = ptr;


This code contains a serious defect. If you execute this code, you will see that the label displays the first string that was assigned to strText. This may surprise you. Why doesn 't the label contain the string that says "Goodbye Mr. Ditka "? After all, doesn 't ptr point to the string that is contained in the strText variable?

Whenever you assign a new string to an AnsiString variable, the AnsiString deallocates whatever memory it previously owned and allocates new memory for the new string. When the new memory is allocated, it is unlikely to be the same memory that was originally returned by the c_str function.

The second line of code in the example above stores the pointer returned by c_str for later use. After the pointer is stored, a new string is assigned to the AnsiString variable. At this point, the strText variable deallocates the first string and allocates memory for the new string. Now ptr points to memory that has been deleted. When you copy that memory into the label, you see the remnants of the original string. For larger strings, the label may contain garbage characters, or the label may appear to be truncated. De-referencing the data in the ptr variable may also cause an access violation because you are using memory that the application no longer owns.

Storing the result of c_str can lead to problems that are more difficult to track down. For example:

char *ptr1 = Edit1-> Text.c_str();

char *ptr2 = Edit2-> Text.c_str();


Label1-> Caption = "Edit1 contains " + AnsiString(ptr1);

Label2-> Caption = "Edit2 contains " + AnsiString(ptr2);


On the surface, the code looks like it should work. Sure, we store the pointer returned from c_str, but nothing is done that would cause the string to be re-allocated as in the first example. However, if you test this code, you will see that it does not work. Sometimes the labels will both display the string from the second edit box, and sometimes they contain garbage.

The problem is that the Text property of TEdit returnes a new AnsiString by value. This new AnsiString object is a temporary object. Temporary objects don 't last forever. They only hang around as long as they are needed. They are destroyed before the next line of code executes.

In this code example, the temporary object is only needed for the call to c_str. Once the c_str method has been called, the temporary object is destroyed because it is no longer needed. Here is the catch. Deleting the temporary object deletes the memory that was pointed to by c_str, which means that ptr1 points to deleted memory. You can see the destruction of the temporary object by viewing the assembly code generated by these statements.

// assembly output for the statement

char *ptr1 = Edit1-> Text.c_str();




mov ...

lea ...

call System::AnsiString::AnsiString(); // create temp object

mov ...

inc ...

mov ...

call Controls::TControl::GetText(); // load Caption into temp AnsiString

lea ...

call System::AnsiString::c_str() // get c_str of temp object

mov ...

dec ...

lea ...

mov ...

call System::AnsiString::~AnsiString // delete temp object


All of this code is generated by the one statement where ptr1 is assigned the value of Edit1-> Text.c_str(). Before the next line of code executes, the temporary AnsiString object is destroyed. Deleting the temporary AnsiString object renders the previous c_str result worthless, and that is exactly what happens (and it 's exactly what should happen, the compiler is obeying the standard by cleaning up temporary objects in this manner).

The moral of this story is to avoid saving the result from AnsiString::c_str because you run the risk of keeping a pointer to memory that has been de-allocated.


[解决办法]
void __fastcall TForm1::Button1Click(TObject *Sender)
{
String str= "sssss ";
String str1= " ";
swapstr(str1,str);

ShowMessage(str1);
}
//---------------------------------------
void TForm1::swapstr(String &s1,String &s2)
{
s1=s2;
}

热点排行