2017-02-15 2 views
-2

В приведенном ниже коде я использую одну функцию свопинга для обмена двумя типами данных. Но я получаю много ошибок.Обмен двумя структурами и двумя int с использованием указателей void в функциональном параметре

Может ли кто-нибудь помочь мне в том, что я делаю неправильно?

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

// Определение структуры, которое я пытаюсь поменять местами.

struct swapNum 
{ 
    int sal; 
    char *c; 
}; 

// Функция обмена, которую я использую для обмена с параметрами функции void.

void swap(void *a,void *b, int size) 
{ 
    if(size == sizeof(*a)) 
    { 
     struct swapNum temp; 
     memcpy(temp,a,sizeof(*a)); 
     memcpy(a,b,sizeof(*b)); 
     memcpy(b,temp,sizeof(*temp)); 
    } 
    if(size == sizeof(int)) 
    { 
     int *temp; 
     *temp = *a; 
     *a = *b; 
     *b = *a; 
    } 
} 

Главный драйвер части программы.

int main(void) { 
    char a[10] = "vivek"; 
    char b[10] = "mishra"; 
    struct swapNum *A= malloc(sizeof(struct swapNum)); 
    struct swapNum *B = malloc(sizeof(struc swapNum)); 
    A->sal = 23; 
    A->c = a; 

    B->sal = 64; 
    B->c = b; 

    swap(&A,&B,sizeof(A)); 

    int x=10,y=20; 
    swap(&x,&x,sizeof(b)); 
    printf("After swapping x : %d y: %d",x,y); 

    return 0; 
} 

Ошибки, которые я получаю.

prog.c: In function 'swap': 
prog.c:16:9: error: incompatible type for argument 1 of 'memcpy' 
     memcpy(temp,a,sizeof(*a)); 
     ^
In file included from prog.c:2:0: 
/usr/include/string.h:46:14: note: expected 'void * __restrict__' but  argument is of type 'struct swapNum' 
extern void *memcpy (void *__restrict __dest, const void *__restrict __src, 
      ^
prog.c:18:30: error: invalid type argument of unary '*' (have 'struct  swapNum') 
     memcpy(b,temp,sizeof(*temp)); 
          ^
prog.c:18:9: error: incompatible type for argument 2 of 'memcpy' 
     memcpy(b,temp,sizeof(*temp)); 
     ^
In file included from prog.c:2:0: 
/usr/include/string.h:46:14: note: expected 'const void * __restrict__' but  argument is of type 'struct swapNum' 
extern void *memcpy (void *__restrict __dest, const void *__restrict __src, 
      ^
prog.c:23:9: warning: dereferencing 'void *' pointer 
     *temp = *a; 
     ^
prog.c:23:17: warning: dereferencing 'void *' pointer 
     *temp = *a; 
       ^
prog.c:23:9: error: invalid use of void expression 
     *temp = *a; 
     ^
prog.c:24:9: warning: dereferencing 'void *' pointer 
     *a = *b; 
     ^
prog.c:24:14: warning: dereferencing 'void *' pointer 
     *a = *b; 
      ^
prog.c:2 
4:9: error: invalid use of void expression 
    *a = *b; 
     ^
prog.c:25:9: warning: dereferencing 'void *' pointer 
    *b = *a; 
    ^
prog.c:25:14: warning: dereferencing 'void *' pointer 
     *b = *a; 
      ^
prog.c:25:9: error: invalid use of void expression 
     *b = *a; 
     ^
prog.c: In function 'main': 
prog.c:33:36: error: 'struc' undeclared (first use in this function) 
    struct swapNum *B = malloc(sizeof(struc swapNum)); 
            ^
prog.c:33:36: note: each undeclared identifier is reported only once for  each function it appears in 
prog.c:33:42: error: expected ')' before 'swapNum' 
    struct swapNum *B = malloc(sizeof(struc swapNum)); 
             ^
+0

Почему бы не попробовать с 'void swap (struct swapNum * a, struct swapNum * b, int size)'? – yano

+1

Почему вы не печатаете, что такое 'sizeof (* a)', поэтому вы можете видеть, что компилятор считает размером разыменованного указателя пустоты. – bruceg

+0

@yano Если я использую void swap (struct swapNum * a, struct swapNum * b, int size), то эта функция никогда не сможет обменять два целых числа. – Vivek

ответ

0

Есть две проблемы:

struct swapNum *A= malloc(sizeof(struct swapNum)); 
struct swapNum *B = malloc(sizeof(struc swapNum)); 
A->sal = 23; 
A->c = a; 

B->sal = 64; 
B->c = b; 

swap(&A,&B,sizeof(A)); 

sizeof(A) возвращает размер указателя, вам нужно sizeof(*A), чтобы получить правильный размер объекта.

И вы не хотите, чтобы адрес &A и &B, потому что они уже указатели, изменение

swap(A,B,sizeof(*A)); 

Вторая проблема заключается в swap функции:

void swap(void *a,void *b, int size) 
{ 
    if(size == sizeof(*a)) 
    { ... 

компилировать с предупреждениями :

warning: invalid application of ‘sizeof’ to a void type 

Как принято ложил на @BLUEPIXY в комментариях, используйте временный:

void swap(void *a,void *b, size_t size) 
{ 
    void *temp = malloc(size); 

    if (temp) { 
     memcpy(temp, a, size); 
     memcpy(a, b, size); 
     memcpy(b, temp, size); 
     free(temp); 
    } 
} 
+0

Я изменил его, но я все еще получаю ошибки. prog.c: 16: 9: ошибка: несовместимый тип для аргумента 1 из 'memcpy' memcpy (temp, a, sizeof (a)); ^ prog.c: 18: 9: ошибка: несовместимый тип для аргумента 2 из 'memcpy' memcpy (b, temp, sizeof (temp)); ^ prog.c: 23: 9: предупреждение: разыменование «void * 'pointer * temp = * a; ^ prog.c: 23: 17: предупреждение: разыменование «void * 'pointer * temp = * a; ^ prog.c: 23: 9: ошибка: недействительное использование выражения void * temp = * a; ^ – Vivek

0

Вот способ реализации обобщенной функции подкачки, который не требует malloc для вашего временного:

void swap_by_bytes (void *a, void *b, size_t sz) { 
    char tmp; 
    char *ap = a; 
    char *bp = b; 
    while (sz--) { 
     tmp = *ap; 
     *ap++ = *bp; 
     *bp++ = tmp; 
    } 
} 

В то время как побайтно работ отлично, вы могли бы улучшить вещи, копируя слово в слово.

void swap_by_words (void *a, void *b, size_t sz) { 
    unsigned tmp; 
    char *ap = a; 
    char *bp = b; 
    while (sz >= sizeof(tmp)) { 
     memcpy(&tmp, ap, sizeof(tmp)); 
     memmove(ap, bp, sizeof(tmp)); 
     memcpy(bp, &tmp, sizeof(tmp)); 
     ap += sizeof(tmp); 
     bp += sizeof(tmp); 
     sz -= sizeof(tmp); 
    } 
    if (sz > 0) swap_by_bytes(ap, bp, sz); 
} 

Если размер не кратен размеру слова, остаток заменяется байтами. Обратите внимание на использование memmove на случай, если a и b перекрываются.

Наконец, вы можете использовать VLA, если ваша платформа поддерживает его. Однако C.2011 сделала VLA дополнительной функцией, поэтому вам нужно проверить ее доступность.

void swap (void *a, void *b, size_t sz) { 
#ifdef __STDC_NO_VLA__ 
    swap_by_words(a, b, sz); 
#else 
    char tmp[sz]; 
    memcpy(tmp, a, sz); 
    memmove(a, b, sz); 
    memcpy(b, tmp, sz); 
#endif 
} 
Смежные вопросы