Как вернуть массив 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 [] на нем.
Большое спасибо за это, его, очевидно, очень фундаментальное, но кое-что я делал неправильно какое-то время.
Ответы
Ответ 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 в своей функции как статический и вернуть его адрес (как уже было предложено).