Assigning a char pointer like you did doesn't copy a string. And you don't need unsafe code to convert strings:
static void Main(string[] args)
{
IntPtr ptr = Marshal.AllocHGlobal(255);
Error(ptr);
string msg = Marshal.PtrToStringAnsi(ptr);
Console.Write(msg);
Marshal.FreeHGlobal(ptr);
}
public static void Error(IntPtr ptr)
{
string error = "This is just testing ... Again Testing";
IntPtr ptr2 = Marshal.StringToHGlobalAnsi(error);
byte[] ptr2Bytes = new byte[error.Length + 1];
Marshal.Copy(ptr2, ptr2Bytes, 0, ptr2Bytes.Length);
Marshal.FreeHGlobal(ptr2);
Marshal.Copy(ptr2Bytes, 0, ptr, ptr2Bytes.Length);
}