Что решает освободить локальное распределение по возвращении? - PullRequest
0 голосов
/ 21 января 2011

Итак, у меня есть 2 фрагмента кода, один из которых работает, а другой нет.Первая часть была просто тестом, чтобы выяснить, останется ли указатель на символ действительным после того, как он будет возвращен из локального распределения.По какой-то причине это работает:

    char* test(){
        char* rawr="what";
        return rawr;  
    }

Но этот не работает:

    char* folderfromfile(char* filz) //gets the folder path from the file path
    {
            //declarations
            int  lastslash=-1;
            int  i        =0;
            char rett[256];

        for(i;(int)filz[i]!=0;i++)
                if(filz[i]=='\\')
                    lastslash=i;     //records the last known backslash

        if(lastslash==-1)
                return "";           //didn't find a backslash

        for(i=0;i<=lastslash;i++)
                rett[i]=filz[i];     // copies to new string

        rett[i]    =0; //end of string
        cout << &rett << "====" << rett << endl;

        system("pause>nul");//pause so i can watch over the memory before it deallocates
        return rett;  
    }

Могу поспорить, что есть лучший способ выполнить эту задачу, удалив имя файла изполный путь, но сейчас я просто пытаюсь выяснить, почему этот указатель на символ удаляется, а другой - нет.Если бы мне пришлось угадывать, я бы сказал, потому что я объявил это по-другому, или потому что он больше.Да, я мог бы просто передать еще один указатель на символ в качестве аргумента этой функции, но это не ответило бы на мой вопрос.

Ответы [ 2 ]

5 голосов
/ 21 января 2011

rett выделяется в стеке, поэтому при возврате метода его пространство памяти перестает быть допустимым.

rawr указывает на литерал, который ваш компилятор может зарезервировать в памяти (только для чтения) при запуске программы.

Оба подхода неверны.

Вам необходимо выделить буфер с помощью new (или malloc в C) или использовать std :: string.

0 голосов
/ 21 января 2011
char* test(){
    char* rawr="what";
    return rawr;  
}

Строковый литерал "what" - это , а не , выделенный в стеке - он остается действительным на протяжении всей жизни программы.Однако это НЕ должно быть изменено.Сам указатель rawr находится в стеке, но это проблема, только если вы пишете такие вещи, как &rawr, получая указатель на указатель.

char* folderfromfile(char* filz){ //gets the folder path from the file path
    int lastslash=-1,i=0;char rett[256]; //declarations
    ///// ...
    return rett;  
}

Это, однако, помещает массив в стеке.rett здесь неявно &rett[0], то есть получает указатель на первый элемент массива, который очень много в стеке и является недопустимым после возврата.

...