1

in this code i am trying to simulate a task that populats an array of structs, ...unsafe to get as much throughoutput as can be achived.

the issue is that i when calling the fucntion and itterating on the result shows different characters but within the scope of GetSomeTs() it's fine.

so just before the return i test one of the elements and it prints the correct value.

this is the testing struct.

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;
    }

but using it anywhere else printing garbage.

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));
        }
}
Avia Afer
  • 866
  • 2
  • 8
  • 29

1 Answers1

1

When you allocate memory with stackalloc that memory only exists until the function returns in which you have allocated it. You are returning a pointer to memory that is no longer allowed to be accessed.

Hard to recommend a fix because it's unclear what you want to achieve. Probably, you should just use a managed char[].

Encoding.Default.GetBytes is pretty slow so that's likely to be your hotspot anyway and the rest is less important. i.ToString() also is quite slow and produces garbage. If you are after perf then stop creating unneeded objects all the time such as SomeValChars. Create it once and reuse.

usr
  • 168,620
  • 35
  • 240
  • 369
  • first thanks for your answer, and if i try to copy the result to manged char[] before exiting, via array copy i will loose the whole consept of doing it fast, cause it will be another task that consume time so better stay with char[] from begining?, the purpose of this code is to initialise an array of structs with values as fast as possible the idle type would be string, i am trying to gain performance vs the normal List – Avia Afer Oct 19 '15 at 20:51
  • Do you understand that the stackalloc approach has no chance of working because the memory is gone when the method returns? – usr Oct 19 '15 at 20:53
  • i do, that is a rule by design , though not if you copy the block ..say `T1.block` is char[] and i bother to go to unmanaged code as in the function `GetSomeTs()` all the same but in the end i will somehow (need to study casting `char*` to `char[]`) thus copy the content of tmpCap... it will sustain the value outside of GetSomeTs() though did i gain anything through all the process vs `char[]`= `char[]` or `string` = `string`, is the real question – Avia Afer Oct 19 '15 at 21:07
  • So, ask yourself where you are going to copy to. Using stackalloc can only slow you down here by introducing a needless intermediate buffer. – David Heffernan Oct 19 '15 at 21:37
  • You can't cast from pointer to array. An array is a full object that also stores a length. It's more than a pointer. The right way forward is to allocate an array in the first place, fill it and return it. – usr Oct 20 '15 at 09:02
  • I think you should implement the perf suggestions that I made. They have 10x more impact than avoiding this array allocation. – usr Oct 20 '15 at 09:02
  • am working on a new model using unsafe ... interop to dll c++ using pointers, see if i get any change – Avia Afer Oct 20 '15 at 12:30
  • @usr, hey i think i got the best solution, please could you find the time and comment on this posted answer ? http://stackoverflow.com/questions/33219095/faster-way-to-return-data-as-an-array-interoping-c?answertab=active#tab-top – LoneXcoder Oct 20 '15 at 16:24