Подтвердить что ты не робот

Как вернуть массив char, созданный в функции?

Я плохо программировал какое-то время, и я только что понял. Я ранее создал много функций, которые возвращают символьные строки как char массивы (или, по крайней мере, указатели на них).

На днях кто-то указал, что когда мои функции возвращают массивы char, на которые указывают мои функции, вышли из области видимости, и я по существу теперь указываю на случайный бит памяти (неприятный висячий указатель).

Я не замечал этого какое-то время, потому что массивы char при выводе на консоль не выглядели поврежденными (вероятно, потому, что не было времени для перезаписывания этих данных). Однако я заметил это, когда возвращал строковый буфер (массив char), созданный при чтении последовательного порта, который был часто поврежден.

Итак, как лучше мне это сделать?

Мой плохой код выглядит следующим образом:

#include <cstdlib>
#include <iostream>

using namespace std;

char* myBadFunction(){
    char charArray[] = "Some string\n";
    char* charPointer = charArray;
    return charPointer;
}


int main(int argc, char** argv) {

    cout << myBadFunction();

    return 0;
}

Я понимаю, что я должен, возможно, выделить память в программе перед вызовом функции или создать глобальную переменную, чтобы поместить возвращаемую строку, но если моя вызываемая функция используется многими различными программами, когда она должна знать размер буфер передается в него заранее и когда эта память должна быть удалена?

Следующий код также не делает то, что я хочу, чтобы он правильно:

#include <cstdlib>
#include <iostream>

using namespace std;

void fillArray(char* charPointer){
    char charArray[] = "Some string\n"; // Create string
    charPointer = charArray; // Not correct, want to fill predefined array with created string
    return;
}


int main(int argc, char** argv) {

    char predefinedArray[50] = {0};
    fillArray(predefinedArray);
    cout << predefinedArray;

    return 0;
}

Я хочу заполнить массив, на который указывает обработчик, но это не происходит в коде выше.

Также, когда я должен использовать новую команду [] для создания моего массива? это необходимо? и когда я должен называть delete [] на нем.

Большое спасибо за это, его, очевидно, очень фундаментальное, но кое-что я делал неправильно какое-то время.

4b9b3361

Ответ 1

Самый простой способ - вернуть std::string, и если вам нужен доступ к внутреннему массиву char, используйте std::string::c_str().

#include <iostream>
#include <string>

using namespace std;

string myGoodFunction(){
    char charArray[] = "Some string\n";
    return string(charArray);
}


int main(int argc, char** argv) {  
    cout << myGoodFunction();
    return 0;
}

Если вам нужно вернуть что-то другое, кроме массива char, помните, что указатели могут использоваться как итераторы. Это позволяет вам инкапсулировать массив в вектор или аналогичную структуру:

vector<int> returnInts() {
    int someNums[] = { 1, 2, 3, 4 };
    return vector<int>(someNums, someNums + 4);
}

Ответ 2

У вас есть два варианта возврата массива в С++. Вы можете заполнить предварительно выделенную память (хорошо) или выделить свою функцию внутри функции и вернуть ее (плохую). Причина, по которой первый предпочтительнее, заключается в том, что он повторно обеспечивает правильную утилизацию выделенной памяти.

Основной пример будет выглядеть следующим образом:

void fillArray(char* buffer, int sz) {
  char text[] = "hello there!";
  if (sizeof(text)>sz) {
    // overflow! Buffer is too small!
    return;
  }
  for (int n=0;n<sizeof(text);n++) {
    buffer[n] = text[n];
  }
}

int main() {
  char* buffer = new char[30]; // allocates a buffer of 30 bytes.
  fillArray(buffer,30);
  cout << buffer;
  delete [] buffer;
}

/* note that it would be easier to use static memory in this example */

Это не сложно, когда вы думаете о проблеме.

Ответ 3

Объявите массив как "статический" varible и верните его своим адресом. Этот код работает, но вызывает предупреждение:

#include <cstdlib>
#include <iostream>
using namespace std;

char* myBadFunction(){
    static char charArray[] = "Some string\n";    // insert "static"
    // char* charPointer = charArray;  
    return charArray;             // charArray is a pointer to the static array
}                                 // after returning static varibles stay safe
int main(int argc, char** argv) {
    cout << myBadFunction();
    return 0;
}

Ответ 4

"Некоторая строка \n" является строковым литералом и поэтому существует для времени жизни программы, поэтому было бы справедливо следующее:

#include <cstdlib>
#include <iostream>

using namespace std;

char* myGoodFunction(){
    char* charPointer = "Some string\n";
    return charPointer;
}

int main(int argc, char** argv) {
    cout << myGoodFunction();

    return 0;
}

Конечно, это полезно, только если функция всегда возвращает одну и ту же строку. Если возвращаемая строка может меняться (в общем случае), вы можете объявить массив char в своей функции как статический и вернуть его адрес (как уже было предложено).