malloc, область действия, инициализация (или ее отсутствие) - PullRequest
0 голосов
/ 08 декабря 2011

Вот код:

 // allocation  
void allocateSymbolStorage(char **pepperShakerList, char **pepperList)
{   
    //  allocate storage for an array of pointers
    pepperShakerList = (char **) malloc(MAX_PEPPER_SHAKERS * sizeof(char *));

    for (int i = 0; i < MAX_PEPPER_SHAKERS; i++)
    {
        if ((pepperShakerList[i] = (char *) malloc(MAX_SHAKERNAME_LENGTH * sizeof(char))) == NULL)
            fatalError("failed pepperShakerList alloc");
    }

    //  allocate storage for an array of pointers 
    pepperList = (char **) malloc(MAX_PEPPERS * sizeof(char *));

    for (int i = 0; i < MAX_PEPPERS; i++)
    {
        if ((pepperList[i] = (char *) malloc(MAX_PEPPER_LENGTH * sizeof(char))) == NULL)
            fatalError("failed pepperList alloc");
    }
}

void buildPepperShakers(void)
{
    char **pepperShakerList, **pepperList; 

    allocateSymbolStorage(pepperShakerList, pepperList);

    // ....

    freeSymbolStorage(pepperShakerList, pepperList);
}

Вот ошибка VS 2010: : предупреждение C4700: неинициализированная локальная переменная 'pepperList'

Вот путаница: Почему ошибка, если char ** выделяется в функции allocate? Это вопрос того, что выпадает из сферы видимости?

Ответы [ 2 ]

0 голосов
/ 08 декабря 2011

Если предположить, что вы говорите о pepperList, а не symbolList, И при условии, что ваш код в allocSymbolStorage отражает то, что вы хотите сделать, то VC правильно жалуется.

В его нынешнем виде ваш код может произойти сбой, потому чтов buildPepperShakers () вы НЕ получаете обратно значения от allocateSymbolStorage.

Таким образом, ваш allocateSymbolStorage должен быть объявлен как:

void allocateSymbolStorage(char ***pepperShakerList, char ***pepperList)

ТО, когда вы передаете адреса локальных переменных-указателей в buildPepperShakersа именно pepperList и pepperShakerList функции распределения, чтобы она могла ТО делать распределения согласно ответу TJD.То есть:

void buildPepperShakers(void) {
       char **pepperShakerList, **pepperList;
       allocateSymbolStorage(&pepperShakerList, &pepperList); 
}

конечно ваше тело allocateSymbolStorage теперь становится:

void allocateSymbolStorage(char ***pepperShakerList_p, char ***pepperList_p)
{   
    char **pepperShakerList, **pepperList;
    //  allocate storage for an array of pointers
    pepperShakerList = (char **) malloc(MAX_PEPPER_SHAKERS * sizeof(char *));

    for (int i = 0; i < MAX_PEPPER_SHAKERS; i++)
    {
        if ((pepperShakerList[i] = (char *) malloc(MAX_SHAKERNAME_LENGTH * sizeof(char))) == NULL)
            fatalError("failed pepperShakerList alloc");
    }

    //  allocate storage for an array of pointers 
    pepperList = (char **) malloc(MAX_PEPPERS * sizeof(char *));

    for (int i = 0; i < MAX_PEPPERS; i++)
    {
        if ((pepperList[i] = (char *) malloc(MAX_PEPPER_LENGTH * sizeof(char))) == NULL)
            fatalError("failed pepperList alloc");
    }

    *pepperShakerList_p = pepperShakerList;
    *pepperList_p = pepperList;

}

и теперь VC не должен жаловаться.Хотя это уродливый способ управления памятью ваших объектов :-)

0 голосов
/ 08 декабря 2011

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

*pepperShakerList = (char *) malloc(MAX_PEPPER_SHAKERS * sizeof(char *));
...