C# 在结构[]中使用不安全字符*提取字符值时出现问题
在这段代码中,我试图模拟一个填充结构数组的任务, …尽可能多地完成任务是不安全的 问题是我在调用函数并对结果进行评级时 显示不同的字符,但在C# 在结构[]中使用不安全字符*提取字符值时出现问题,c#,arrays,string,character,unsafe,C#,Arrays,String,Character,Unsafe,在这段代码中,我试图模拟一个填充结构数组的任务, …尽可能多地完成任务是不安全的 问题是我在调用函数并对结果进行评级时 显示不同的字符,但在GetSomeTs()的范围内。 所以在返回之前,我测试了其中一个元素,它输出了正确的值 这是测试结构 public unsafe struct T1 { public char* block = stackalloc char[5];<--will not compile so the process will be done within
GetSomeTs()的范围内。
所以在返回之前,我测试了其中一个元素,它输出了正确的值
这是测试结构
public unsafe struct T1
{
public char* block = stackalloc char[5];<--will not compile so the process will be done within a local variable inside a method
}
public unsafe struct T1
{
public char* block;
}
static unsafe T1[] GetSomeTs(int ArrSz)
{
char[] SomeValChars = { 'a', 'b', 'c', 'd', 'e' };
T1[] RtT1Arr = new T1[ArrSz];
for (int i = 0; i < RtT1Arr.Length; i++)
{
char* tmpCap = stackalloc char[5];
for (int l = 0; l < 5; l++)
{
SomeValChars[4] = i.ToString()[0];
tmpCap[l] = SomeValChars[l];
}
RtT1Arr[i].block = tmpCap;//try 1
//arr[i].block = &tmpCap[0];//try 2
}
// here its fine
Console.WriteLine("{0}", new string(RtT1Arr[1].block));
return RtT1Arr;
}
公共不安全结构T1
{
public char*block=stackalloc char[5];当您使用stackalloc
分配内存时,该内存仅存在,直到函数返回您分配的内存为止。您返回的是指向不再允许访问的内存的指针
很难推荐修复方案,因为不清楚您想要实现什么。也许,您应该只使用托管的char[]
Encoding.Default.GetBytes
非常慢,因此这很可能是您的热点,而其余的就不那么重要了。i.ToString()
也非常慢,会产生垃圾。如果您追求性能,请停止一直创建不需要的对象,例如SomeValChars
。创建一次并重新使用。首先感谢您的回答,如果我尝试将结果复制到Managed char[]在退出之前,通过数组复制,我将放弃快速完成任务的想法,因为这将是另一项耗费时间的任务,因此最好使用char[]从一开始,这段代码的目的是尽可能快地初始化一个具有值的结构数组。空闲类型将是字符串,我试图获得与普通列表相比的性能。您是否理解stackalloc方法没有工作的机会,因为当方法返回时内存就不存在了?我知道,这是一个设计规则,t如果你复制块就不会了。比如说T1.block
是char[],我费心去非托管代码,就像在函数GetSomeTs()
中一样,但最后我还是会(需要研究如何将char*
转换成char[]
)这样复制tmpCap的内容……它将保持GetSomeTs()之外的值尽管与char[]相比,我在整个过程中获得了什么
或string
=string
,才是真正的问题。所以,问问自己要复制到哪里。使用stackalloc只能通过引入不必要的中间缓冲区来降低速度。你不能从指针强制转换到数组。数组是一个完整的对象,也存储长度。它不仅仅是指针。正确的方法是ard首先分配一个数组,填充它并返回它。
void Main()
{
T1[] tstT1 = GetSomeTs(10);
for (int i = 0; i < 10; i++)
{
Console.WriteLine("{0}", new string(tstT1[i].block));//,0,5, Encoding.Default));
}
}