может ли пустота * быть malloced?

Я использую ODBC в C. Они имеют определенный тип:

typedef void *          SQLPOINTER;
typedef unsigned int    SQLUINTEGER;

У меня есть функция alloc_buffer:

void db_alloc_buffer(SQLUINTEGER buffSize, SQLPOINTER *Ptr)
{
    *Ptr = malloc(buffSize);
    memset(*Ptr, ' ', buffSize); 
}

Является ли является безопасным / правильным для de reference Ptr? или могу я сделать:

void db_alloc_buffer(SQLUINTEGER buffSize, SQLPOINTER *Ptr)
{
    Ptr = malloc(buffSize);
    memset(Ptr, ' ', buffSize); 
}

2 ответа

  1. Нет, разыменование не безопасноPtr, как во второй версии. Ptrявляется указателем на указатель, а не указателем непосредственно на буфер. Эта функция предназначена для выделения буфера, который может использоваться вызывающим. Вызывающий объект предоставляет адрес своей переменной указателя, и ваша функция должна выделить буфер и установить эту переменную в адрес буфера, и она делает это путем разыменования Ptrс результатом malloc().

    Если вы назначаете Ptrвместо*Ptr, то это просто назначает локальной переменной, а не переменной вызывающего абонента.

  2. может ли пустота * быть malloced?

    Да. Почему бы и нет: void** p = malloc(sizeof(void*));

    Является ли является безопасным / правильным для de reference Ptr?

    Безопасно? Только если Ptrуказывает на допустимую память. Если кто-то звонитdb_alloc_buffer(n, NULL), то это определенно не безопасно.

    Правильно? Это зависит от того, что вы пытаетесь сделать. Второй код не кажется полезным, потому что вы игнорируете значение аргумента, который был передан как Ptr.

    Первая версия кажется более полезной, поскольку она, по крайней мере, имеет некоторые наблюдаемые эффекты вне функции, а именно то, что она изменяет тоSQLPOINTER, что было передано как Ptr.

    Кажется, что вы хотите что-то вроде этого:

    SQLPOINTER db_alloc_buffer(SQLUINTEGER buffSize)
    {
        SQLPOINTER Ptr = malloc(buffSize);
        if (Ptr == NULL) return NULL;
        memset(Ptr, ' ', buffSize); 
        return Ptr;
    }