Как иметь указатель char как параметр out для функции С++

Я новичок на С++. Я пытаюсь использовать указатель char как параметр out для функции. Но изменения, внесенные в функцию, не отражаются в основной функции. Что я делаю неправильно?

void SetName( char *pszStr )
{
    char* pTemp = new char[10];
    strcpy(pTemp,"Mark");
    pszStr = pTemp;
}

int _tmain(int argc, _TCHAR* argv[])
{
    char* pszName = NULL;
    SetName( pszName );
    cout<<"Name - "<<*pszName<<endl;
    delete pszName;
    return 0;
}

Ответ 1

Ваш указатель копируется в стек, и вы назначаете указатель стека. Вам нужно передать указатель на указатель, если вы хотите изменить указатель:

void SetName( char **pszStr )
{
    char* pTemp = new char[10];
    strcpy(pTemp,"Mark");
    *pszStr = pTemp; // assign the address of the pointer to this char pointer
}

int _tmain(int argc, _TCHAR* argv[])
{
    char* pszName = NULL;
    SetName( &pszName ); // pass the address of this pointer so it can change
    cout<<"Name - "<<*pszName<<endl;
    delete pszName;
    return 0;
}

Это решит вашу проблему.


Однако здесь есть и другие проблемы. Во-первых, вы разыскиваете свой указатель перед печатью. Это неверно, ваш указатель является указателем на массив символов, поэтому вы хотите распечатать весь массив:

cout<<"Name - "<<pszName<<endl;

Теперь у вас будет только первый символ. Также, вам нужно использовать delete [] для удаления массива:

delete [] pszName;

Большие проблемы, однако, находятся в вашем дизайне.

Этот код C, а не С++, и даже тогда он не является стандартным. Во-первых, функция, которую вы ищете, main:

int main( int argc, char * argv[] )

Во-вторых, вместо указателей следует использовать references:

void SetName(char *& pszStr )
{
    char* pTemp = new char[10];
    strcpy(pTemp,"Mark");
    pszStr = pTemp; // this works because pxzStr *is* the pointer in main
}

int main( int argc, char * argv[] )
{
    char* pszName = NULL;
    SetName( pszName ); // pass the pointer into the function, using a reference
    cout<<"Name - "<<pszName<<endl;
    delete pszName;
    return 0;
}

Кроме того, обычно лучше просто вернуть вещи, если вы можете:

char *SetName(void)
{
    char* pTemp = new char[10];
    strcpy(pTemp,"Mark");
    return pTemp;
}

int main( int argc, char * argv[] )
{
    char* pszName = NULL;
    pszName = SetName(); // assign the pointer
    cout<<"Name - "<<pszName<<endl;
    delete pszName;
    return 0;
}

Есть что-то, что делает все это лучше. С++ имеет строковый класс:

std::string SetName(void)
{
    return "Mark";
}

int main( int argc, char * argv[] )
{
    std::string name;

    name = SetName(); // assign the pointer

    cout<<"Name - "<< name<<endl;

    // no need to manually delete
    return 0;
}

Если это все можно упростить, если вы хотите:

#include <iostream>
#include <string>

std::string get_name(void)
{
    return "Mark";
}

int main(void)
{
    std::cout << "Name - " << get_name() << std::endl;        
}

Вы должны работать над своим форматированием, чтобы сделать чтение более понятным. Пространства между оператором помогают:

cout<<"Name - "<<pszName<<endl;

cout << "Name - " << pszName << endl;

Точно так же, как пробелы между английскими словами помогают, sodoesspacesbetweenyroperators.:)

Ответ 2

Вы также можете использовать ссылку на указатель в этом случае. Кроме того, вы можете быть в курсе двух других ошибок, которые находятся в исходном коде (см. Мои комментарии в фрагменте кода).

 void SetName( char *& pszStr )
 {
     char* pTemp = new char[10];
     strcpy(pTemp,"Mark");
     pszStr = pTemp;
 }

 int _tmain(int argc, _TCHAR* argv[])
 {
     char* pszName = NULL;
     SetName(pszName);

     // Don't need '*' in front of pszName.
     cout<< "Name - " << pszName << endl;

     // Needs '[]' to delete an array.
     delete[] pszName;
     return 0;
 }

Ответ 3

Поскольку вы помечены как С++, почему бы не передать ссылку std::string и не заполнить ее?

void GetName(std::string &strName)
{
    strName = "Mark";
}

Или просто верните std::string:

std::string GetName2()
{
  return "Mark";
}

И назовите его так

std::string strName, strName2;
GetName(strName);
strName2 = GetName2();
assert(strName == "Mark");
assert(strName2 == "Mark");
//strName.c_str() returns the const char * pointer.

Тогда вам не нужно беспокоиться о освобождении памяти.

Ответ 4

То, что вы пишете, это не С++, а C-код, который использует новый вместо malloc, и удаляет вместо бесплатного. Если вы действительно хотите написать код на С++, начните снова. Прочитайте книгу, например Ускоренный С++, который научит вас современному идиоматическому С++.