предупреждение о несовместимом типе указателя - PullRequest
2 голосов
/ 23 марта 2012

У меня есть программа на Си, похожая на приведенную ниже.Я пытаюсь написать обертку поверх malloc с подписью int myAlloc().Эта оболочка должна возвращать 1 при успешном выделении памяти или возвращать 0 в случае неудачного выделения памяти.

#include <stdio.h>
#include <stdlib.h>

int myAlloc(void **ptr, int size)
{
    *ptr = malloc(size);

    if (!ptr)
        return 0;
    else
        return 1;
}

void main()
{
    int *p = NULL;
    myAlloc(&p, sizeof(int));
    printf("%d\n", *p);
}

Когда я компилирую это, я получаю предупреждение «несовместимый тип указателя».Как я могу сделать так, чтобы эта функция вызывалась с любым возможным типом указателя без получения предупреждения?

Можно ли удалить операцию приведения из фактического вызова функции?

Обновить

Я нашел ответ.Вот исправленный код:

#include <stdio.h>
#include <stdlib.h>

int myAlloc(void *ptr,int size)
{
    *(void **)ptr = malloc(size);

    if (!ptr)
        return 0;
    else
        return 1;

}

int main()
{
    int *p = NULL;
    myAlloc(&p, sizeof(int));
    *p = 5;
    printf("%d\n", *p);

    return 1;
}

Ответы [ 9 ]

4 голосов
/ 23 марта 2012

ваша функция, myMalloc принимает указатель на указатель на void, или void** вы передаете ему адрес указателя на int, или int**

Вам необходимо привестиуказатель, который вы передаете, чтобы быть недействительным, например,

myAlloc((void**)&p,sizeof(int));
0 голосов
/ 28 марта 2012
#include <stdio.h>
#include <stdlib.h>

int myAlloc(void *ptr,int size)
{
    *(void **)ptr=malloc(size);
    if(!ptr) return 0;
    else return 1;

}

int main()
{
    int *p=NULL;
    myAlloc(&p,sizeof(int));
    *p=5;
    printf("%d\n",*p);
    return 1;
}
0 голосов
/ 23 марта 2012

Невозможно написать такую ​​функцию в C-совместимом стандарте, поскольку int * и void * не являются совместимыми типами.

(в основном) эквивалентное определение макроса может выглядеть так:

#define myAlloc(PTR, SIZE) (!!(PTR = malloc(SIZE)))
0 голосов
/ 23 марта 2012

В C есть тип void* для общего указателя, но нет типа для общего указателя на указатель.Хуже того, размер указателей разных типов может быть не одинаковым.Следовательно, если ваша функция не знает, какой тип указателя она должна назначить, она не может просто «поместить данные в адрес», потому что размер правого указателя может отличаться от размера назначаемого ей указателя.

Например, ваш код может аварийно завершить работу (и имеет значение UB), если sizeof(int*)<sizeof(void*).

Из-за этого я думаю, что невозможно написать оболочку, как вы хотите.

0 голосов
/ 23 марта 2012

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

void *ptr;
if( (ptr = malloc(1000)) )
{
  /* Do stuff with ptr */
}
else
{
  /* throw a tantrum */
}

Вам действительно нужен код возврата int с дополнительными параметрами сложности?

0 голосов
/ 23 марта 2012

Реальная ошибка, которую я вижу - которая может не совпадать с вашей; мы не можем знать, так как вы забыли показать нам фактический результат - выглядит так:

src.c: In function ‘main’:
src.c:15:17: warning: passing argument 1 of ‘myAlloc’ from incompatible pointer type [enabled by default]
src.c:4:5: note: expected ‘void **’ but argument is of type ‘int **’

Вы передаете своей функции myAlloc переменную int **, но ваша функция написана для принятия переменной void **. Вы можете привести тип указателя в вызове функции следующим образом:

myAlloc((void **)&p,sizeof(int));

А теперь он компилируется без предупреждений.

Возможно, вы захотите прочитать раздел pointers в The C Book , особенно раздел 5.3.5, в котором подробно рассматриваются некоторые из затронутых здесь вопросов.

0 голосов
/ 23 марта 2012

OT: в вашем коде есть ошибка.Вы, вероятно, хотите:

   if(!(*ptr)) return 0;
0 голосов
/ 23 марта 2012

В соответствии с сигнатурой myAlloc, вы должны вызывать его с myAlloc((void**)&p,sizeof(int)), поскольку p равно int* (от ptr до int), а не void* (от ptr до void).

0 голосов
/ 23 марта 2012

p имеет тип int*, в то время как ваша функция принимает void**.

myAlloc((void **)&p,sizeof(int));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...