C указатели void * проблема с буфером - PullRequest
0 голосов
/ 14 сентября 2011

Извините, что связал вас с вещами Си. Функция write () принимает void * buff. И мне нужно вызвать эту функцию из main (), предоставив необходимые данные.

Но когда я печатаю, выдает ошибку. Помоги мне, друзья. Код выглядит следующим образом.

void write(int fd, void *buff,int no_of_pages)
{
  // some code that writes buff into a file using system calls
}

Теперь мне нужно отправить бафф с нужными мне данными.

#include "stdio.h"
#include "malloc.h"
int main()
{
int *x=(int*)malloc(1024);
*(x+2)=3192;

*(x+3)="sindhu";

     printf("\n%d %s",*(x+2),*(x+3));      

     write(2,x,10); //(10=4bytes for int + 6 bytes for char "sindhu");
}

Это предупреждает меня

warning: format ‘%s’ expects type ‘char *’, but argument 3 has type ‘int’

Как я могу удалить это предупреждение

Ответы [ 5 ]

5 голосов
/ 14 сентября 2011

Приведением к действительному типу:

printf("\n%d %s",*(x+2),(char*)(x+3)); 

Примечание. То, что вы делаете, выглядит злым. Я бы пересмотрел этот дизайн!

2 голосов
/ 14 сентября 2011

Все просто: делай, как говорит ошибка. Не передавайте целое число в последовательность форматирования строки.

printf("\n%d %d", *(x+2), *(x+3));
              ^--- note the change
1 голос
/ 14 сентября 2011

Вам нужно использовать символ * для ссылки на строку:

char * cp = "sindhu";
printf("\n%d %s", *(x+2), cp);

будет лучше.

0 голосов
/ 14 сентября 2011
int *x=(int*)malloc(1024);

потерять актерский состав; в этом нет необходимости, и он будет подавлять полезную диагностику, если вы забудете #include stdlib.h или иным образом не получите приведение для malloc в области видимости. Во-вторых, обычно лучше с точки зрения читабельности указывать количество элементов , которое вам нужно, определенного типа, а не количество байт . Вы бы сделали это так:

int *x = malloc(N * sizeof *x);

, который говорит "выделить достаточно памяти для хранения N int значений".

*(x+2)=3192;

Хорошо. Вы присваиваете целочисленное значение 3192 x[2].

*(x+3)="sindhu";

Плохо Джуджу; Я удивлен, что компилятор не запустил эту строку. Вы пытаетесь сохранить значение типа char * в int (поскольку тип x равен int *, тип *(x + 3) равен int). Я не уверен, что вы пытаетесь достичь здесь; если вы пытаетесь сохранить значение указателя в x[3], обратите внимание, что значения указателя не обязательно могут быть представлены в виде int (например, предположим, что char * имеет ширину 4 байта, но int является 2 байта в ширину). В любом случае типы не совместимы, и требуется приведение:

*(x + 3) = (int) "sindhu"; // equivalent to writing x[3] = (int) "sindhu"

Если вы пытаетесь скопировать содержимое строки в буфер, начинающийся с x[3], это определенно неправильный путь; чтобы сделать это «работой» (для достаточно свободных определений «работы»), вам необходимо использовать библиотечные функции strcpy или memcpy:

strcpy((char *) (x + 3), "sindhu"); // note the cast, and the fact that
                                    // x + 3 is *not* dereferenced.  

Что касается проблемы в операторе printf, тип *(x + 3) - это int, а не char *, что несовместимо со спецификатором преобразования %s. Опять же, чтобы сделать эту «работу», вы должны сделать что-то вроде

printf("%d %s\n", *(x + 2), (char *) (x + 3));

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

0 голосов
/ 14 сентября 2011

На самом деле в вашем вопросе есть пара интересных моментов.Во-первых, я удивлен, что printf генерирует предупреждение, которое весьма полезно для вашего компилятора, так как по сути printf не является безопасным по типу, поэтому предупреждение не требуется.Во-вторых, я действительно поражен тем, что ваш компилятор разрешает это:

*(x+3) = "sindhu";

Я почти уверен, что это должно быть ошибкой или, по крайней мере, предупреждением, без явного приведения.Обратите внимание, что "sindhu" имеет тип const char*, а ваш массив является массивом типа int.По сути, вы делаете это, помещая адрес памяти строки в 4-е целое число в вашем массиве.Теперь важно то, что это делает очень опасное предположение, что:

sizeof(int) == sizeof(char*)

Это может быть легко не так;в частности, многие 64-разрядные системы не обладают этим свойством.

Ответ Bitmask исключит предупреждение, которое вы получаете, однако, как он предполагает, я настоятельно рекомендую вам изменить дизайн вашегозапрограммируйте так, чтобы в этом не было необходимости.

Также в качестве одного последнего стилистического момента следует помнить, что по большей части массивы и указатели в C совпадают, это не совсем верно, но достаточно сказать, что *(x+2) эквивалентнодо x[2], что намного проще для глаз при чтении кода.

...