Как перебрать массив указателей на символы, возвращаемый функцией в cpp - PullRequest
0 голосов
/ 22 января 2020

Я создаю функцию, которая создает массив из 28 случайных символов из az. Когда я пытаюсь перебрать массив указателей из main, я получаю неправильные значения.

Что мне не хватает?

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

#include <iostream>
#include <ctime>
#define MAX 28

// Generate random char array with a-z values
char* generateRandomString(int length) {
    char random[length];
    for (int i = 0; i < length; i++) {
        // Minimun a ascii = 97
        // Maximun z ascii = 122
        srand(int(time(NULL))); // Timestamp seed generator
        int randomInt = 97 + (rand() % 25);
        char randomChar = randomInt;
        random[i] = randomChar;
    }
    return random;
}

int main() {
    char* random = generateRandomString(MAX);

    for (int i = 0; i < MAX; i++) {
        std::cout << random[i] << std::endl; // (*random)[i] Does not work neither
    }

    return 0;
}

Ответы [ 3 ]

5 голосов
/ 22 января 2020

Вы возвращаете указатель на локальную переменную, которая выходит из области видимости, прежде чем вызывающая сторона сможет использовать ее. Вместо этого просто используйте std::string.

И не звоните srand() несколько раз, звоните только один раз. 1

1: еще лучше, вообще не используйте srand(), используйте вместо этого генератор случайных чисел C ++ из библиотеки <random> .

#include <iostream>
#include <string>
#include <ctime>
#define MAX 28

// Generate random char array with a-z values
std::string generateRandomString(int length) {
    std::string random;
    random.resize(length);
    for (int i = 0; i < length; i++) {
        // Minimun a ascii = 97
        // Maximun z ascii = 122
        int randomInt = 97 + (rand() % 25);
        char randomChar = randomInt;
        random[i] = randomChar;
    }
    return random;
}

int main() {
    srand(int(time(NULL))); // Timestamp seed generator

    std::string random = generateRandomString(MAX);

    for (int i = 0; i < MAX; i++) {
        std::cout << random[i] << std::endl; // (*random)[i] Does not work neither
    }

    return 0;
}
1 голос
/ 22 января 2020
char random[length];

^^ Этот массив ^^ находится в стеке. Когда возвращается generateRandomString(), он возвращает адрес переменной, которая должна составлять d ie. Чтобы память оставалась активной, вам нужно динамически распределять ее:

char* generateRandomString(int length) {
    char* random = new char[length + 1];
    for (int i = 0; i < length; i++) {
        // Minimun a ascii = 97
        // Maximun z ascii = 122
        srand(int(time(NULL))); // Timestamp seed generator
        int randomInt = 97 + (rand() % 25);
        char randomChar = randomInt;
        random[i] = randomChar;
    }
    random[length] = 0; //< null terminate string
    return random;
}

Просто помните, что вам нужно удалить память, когда вы закончили ее использовать!

char* random = generateRandomString(MAX);
...
delete[] random;

В качестве альтернативы используйте std::string:

std::string generateRandomString(int length) {
    std::string random(length);
    for (int i = 0; i < length; i++) {
        // Minimun a ascii = 97
        // Maximun z ascii = 122
        srand(int(time(NULL))); // Timestamp seed generator
        int randomInt = 97 + (rand() % 25);
        char randomChar = randomInt;
        random[i] = randomChar;
    }
    return random;
}
std::string random = generateRandomString(MAX);
...
0 голосов
/ 22 января 2020

Функция generateRandomString возвращает указатель на первый элемент локального массива.

char* generateRandomString(int length) {
    char random[length];

    //...
    return random;
}

После выхода из функции массив не будет живым. Его память может быть перезаписана. Таким образом, указатель будет недействительным. В результате программа имеет неопределенное поведение.

Вместо массива символов вы можете использовать стандартный класс std::string. Это лучше, чем «вручную» динамически выделять массив символов.

Ниже приведена демонстрационная программа, показывающая, как можно обновить вашу исходную программу.

#include <iostream>
#include <string>
#include <cstdlib>
#include<ctime>

std::string generateRandomString( size_t length ) 
{
    std::string s( length, ' ' );

    std::srand( ( unsigned int )std::time( nullptr ) );

    for ( auto &c : s )
    {
        c = 'a' + std::rand() % ( 'z' - 'a' + 1 );
    }

    return s;
}

int main() 
{
    const size_t MAX = 28;

    std::string s = generateRandomString( MAX );

    for ( const auto &c : s ) std::cout << c;
    std::cout << '\n';
}

Ее выходные данные могут выглядеть так Например,

xzefeqsnthhgmfunychcklplccjv

Если вы хотите научиться работать с динамически размещаемыми массивами, программа может выглядеть следующим образом

#include <iostream>
#include <cstdlib>
#include<ctime>

char * generateRandomString( size_t length ) 
{
    char *s = new char[length + 1];

    s[length] = '\0';

    std::srand( ( unsigned int )std::time( nullptr ) );

    for ( size_t i = 0; i < length; i++  )
    {
        s[i] = 'a' + std::rand() % ( 'z' - 'a' + 1 );
    }

    return s;
}

int main() 
{
    const size_t MAX = 28;

    char *s = generateRandomString( MAX );

    std::cout << s << '\n';

    delete [] s;
}

Обратите внимание, что это не очень хорошая идея использовать такие магические числа c как 97. Они делают код неясным. И обычно нет необходимости определять константы в C ++ с помощью директивы #define. Вместо этого используйте объявления констант в C ++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...