Как правильно вернуть значения из функций C / ++? - PullRequest
0 голосов
/ 18 августа 2011

Я сделал несколько приложений, и метод, который я использую, таков:

INT name(char *one,char *two,char buffer[]){
memcpy(buffer,"omg",4);//or using std::string::copy ... that's how I actually return value
...}

и я называю это как:

char returned[255];    
name(first,second,returned);
printf/cout;

Все хорошо. Теперь мой вопрос , этот метод ужасен или это катастрофа? Кроме того, что происходит с выделенной памятью на 255 символов, я имею в виду, есть ли способ перераспределить ее как-то, чтобы немного сэкономить память?

Это так называемая передача по ссылке, в любом случае я должен вернуть несколько значений (от 2 до 10). Если бы мне понадобился только 1, я бы использовал буфер возврата с статическим типом, который я предполагаю.

Спасибо. Напишите ваши любимые методы, пожалуйста, пока я читаю похожие вопросы к этому хе-хе.

Ответы [ 6 ]

3 голосов
/ 18 августа 2011

Просто используйте возвращаемое значение.

std::string name(const std::string& one, const std::string& two)
{
    return "omg";
}

Если вам нужно вернуть переменное число значений, верните вектор:

std::vector<std::string> name(const std::string& one, const std::string& two)
{
    std::vector ret;
    ret.push_back("omg1");
    ret.push_back("omg2");
    ret.push_back("omg3");
    return ret;
}

Если вам нужно вернуть фиксированное числозначений, используйте переход по ссылке, как вы предложили.

void name(const std::string& one, const std::string& two, std::string& ret1, std::string& ret2)
{
    ret1 = "omg1";
    ret2 = "omg2";
}
2 голосов
/ 18 августа 2011

В C ++ вы, вероятно, вернете std :: string и сгенерируете исключение вместо возврата INT (?).

1 голос
/ 18 августа 2011

Для C вы должны передать размер буфера вместе с указателем на него.Передача массива в качестве параметра уменьшает его до указателя, который не содержит никакой информации о размере памяти, на которую он указывает.Примерно так:

int name(char *one, char *two, char *buffer, size_t len);

и назовите это так:

char returned[255];
int result = name("one", "two", returned, sizeof returned);

Для C ++ вы должны использовать std :: string, которая позаботится обо всем за вас, как говорили другие.

1 голос
/ 18 августа 2011

Ваша функция - это катастрофа, поскольку на нее можно легко выполнить атаку переполнения буфера.

Если вы используете C ++, вы можете сделать следующее:

void name(std::string one, std::string& two, std::string& buffer) {
    buffer = "omg";
....}

Тогда вы можетепросто назовите это как:

std::string one, two, buffer;
name(one, two, buffer);
0 голосов
/ 18 августа 2011

Если вы говорите на C ++ - это довольно плохо.Используя std :: strings, вы можете сделать то же самое:

void name(const string &first, const string &second, string &returned) {
    returned = first + second + "omg"; // Or something else
}

И назвать его:

string f = "one", s = "two", r;
name(f, s, r);
cout << r; // 'R' now contains "onetwoomg"

Хотя «мутировать» такие вещи не очень C ++.В C он часто используется, но в C ++ вы обычно присваиваете возвращаемое значение, а не передаете по неконстантной ссылке.

0 голосов
/ 18 августа 2011

Ну, в этом случае returned выделяется в стеке, так что, конечно, вы не можете просто free это (я не знаю, можете ли вы delete это в C ++).Просто используйте его повторно.

Может быть, в этом случае лучше будет вернуть указатель на массив.

...