c # Указатель Указателя символа, символа ** - PullRequest
0 голосов
/ 09 июня 2018

У меня есть этот код (фрагмент), и он работает и работает, но после выхода из всей процедуры procedureInAClass() и продолжения со следующим кодом происходит сбой: "Bad_module_error" .Я не вижу ошибки.

public void procedureInAClass(){ //this code is in a Class, it works but after leaving whole procedure it crashes
char** comment=(char**)Marshal.AllocHGlobal(sizeof(char*)); //comment is in Code a class Member
string aval="some chars in a string";
SToCP(val,  comment) ; //value of String to *comment
CPToS(comment); //**comment to string
}

//this part is in a static class

    public static void SToCP(string s, char** c)//writes string s in *c
    {      
        *c = SToCP(s);
    }
    public static char* SToCP(string s) 
    {
        char* ret= (char*)Marshal.AllocHGlobal( sizeof(char) * (s.Length +1));
        int i;
        byte se = sizeof(char);
        for (i = 0; i < s.Length; i++)
            *(ret + se * i) = s[i];
        *(ret + s.Length * se) = '\0';
        return ret;
    }



public static String CPToS(char** c)
    { 
          return CPToS(*c); //passing the pointer char* which is holded by char** c
    }

public static String CPToS(char* c)
    {
        string ret = "";
        byte s = sizeof(char);//char is two bytes long
        int i = 0;
        while (*(c + s * i) != '\0')//zero terminated string
            ret += *(c + s * i++);
        return ret;
    }

1 Ответ

0 голосов
/ 09 июня 2018

Ваша проблема в том, что вы умножаете свой индекс i на sizeof(char*), но рассматриваете его как char*.Добавление 1 к символу * добавляет размер символа (2 байта) к указателю.Вы писали все остальные символы, а затем продолжали перезаписывать память после выделения строк из-за того, что заходили слишком далеко.

Попробуйте вместо этого:

public static char* SToCP(string s) {
    char* ret = (char*)Marshal.AllocHGlobal(sizeof(char) * (s.Length + 1));
    char* p = ret;
    for (int i = 0; i < s.Length; i++)
        *(p++) = s[i];            
    *(p++) = '\0';
    return ret;
}

Конечно, ваш метод CPToS такженеправильно, поэтому, если вы исправите SToCP, чтобы корректно не записывать поверх другого символа, вам также нужно будет исправить CPToS, иначе он вернет неправильную строку обратно.

Вот исправленная версия CPToSдля совпадения:

public static String CPToS(char* c) {
            string ret = "";
            int i = 0;
            while (*(c +  i) != '\0')//zero terminated string
                ret += *(c +  i++);
            return ret;
        }

SToCP приводил к повреждению стека и к аварийному завершению.

...