Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Очередная проблема с выделением памяти на каноническом Си

29K
08 июня 2009 года
Ander Skirnir
109 / / 08.06.2009
А точнее, с инициализацией двумерного массива.

Код:
void initstr(char **strarr)
{
    int i;

    strarr = (char**) malloc(sizeof(char*) * 14);

    for (i = 0; i < 14; i++)
        *(strarr+i) = malloc(sizeof(char) * 70);

    strcpy(strarr[0], ":(");
    ...
    strcpy(strarr[13], ":(");

    for (i = 0; i < 14; i++)
        *(strarr+i) = (char*) realloc(*(strarr+i), sizeof(char) * (strlen(strarr)+1));

    fprintf(stdout, *strarr); // в этом месте работает
}

void voivoid(void)
{
    char **strarr;

    initstr(strarr);
    fprintf(stdout, *strarr); // а в этом - нет
}
361
08 июня 2009 года
Odissey_
661 / / 19.09.2006
Видимо имя локальной переменной скрывает имя глобальной. Можно например использовать разные префиксы для локальных и для глобальных имен (это на любителя). В целом два имени strarr дают такую проблему.
29K
08 июня 2009 года
Ander Skirnir
109 / / 08.06.2009
Не, тут совсем другая проблема. Я просто хочу, чтобы моя функция изменила значение указателя, который я ей передаю аргументом, а этого не происходит, т.к. в данном случае она как-будто создает его локальную копию и с ней работает.

Вот так, например, всё работает отлично:

Код:
char** initstr ()
{
    char **strarr;
    ....
    return strarr;
}

void voivoid (void)
{
    char strarr**;

    strarr = initstr();

    fprintf(stdout, *strarr);
}


Но тем не менее, я очень хотел бы узнать, как сделать это через аргумент. Пробовал также изощрения типа initstr(&(*strarr)), но не помогло.
2.2K
08 июня 2009 года
REFOT
181 / / 08.04.2005
)) Наверное что-то типа этого:

Код:
void initstr(char **& strarr)
{
    int i;
    strarr = (char**) malloc(sizeof(char*) * 14);
    for (i = 0; i < 14; i++)
        *(strarr+i) = (char*) malloc(sizeof(char) * 70);
    strcpy(strarr[0], ":(");
    strcpy(strarr[13], ":(");
    for (i = 0; i < 14; i++)
        *(strarr+i) = (char*) realloc(*(strarr+i), sizeof(char) * (strlen(strarr)+1));
    fprintf(stdout, *strarr);
}

void voivoid(void)
{
    char **strarr;
    initstr(strarr);
    fprintf(stdout, *strarr);
}


или этого:

Код:
void initstr(char *** strarr)
{
    int i;
    *strarr = (char**) malloc(sizeof(char*) * 14);
    for (i = 0; i < 14; i++)
        *(*strarr+i) = (char*) malloc(sizeof(char) * 70);
    strcpy((*strarr)[0], ":(");
    strcpy((*strarr)[13], ":)");
    for (i = 0; i < 14; i++)
        *(*strarr+i) = (char*) realloc(*(*strarr+i), sizeof(char) * (strlen((*strarr))+1));
    fprintf(stdout, **strarr);
}

void voivoid(void)
{
    char **strarr;
    initstr(&strarr);
    fprintf(stdout, strarr[13]);
}
29K
08 июня 2009 года
Ander Skirnir
109 / / 08.06.2009
Ну да, действительно, большое спасибо :)

А вот первый способ (для справки) не каноничен, т.к. на Си не поддерживаются ссылки (хотя говорят, что в C99 можно) - только указатели :rolleyes:

Прогрессивные люди, которые не теряли время и ушли в Си++ часто этого не знают. Мой препод, например, не знал.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог