Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 21, средняя оценка - 4.76
Gepar
1175 / 531 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
#1

Своя реализация memcpy - C++

01.08.2011, 14:54. Просмотров 2831. Ответов 13
Метки нет (Все метки)

Собственно одно из заданий Дейтела это требует. Но только я столкнулся с тем что
C++
1
void *memcpy(void *s1, const void *s2, size_t n)
получает то указатели на void и возвращает указатель на void. Так как же тогда её реализовать если здесь void... преобразовать как-то в char и скопировать посимвольно? Но так у меня не получается потому как компилятор по прежнему говорит что никакой арифметики с void'ом он сделать не даст (оно то и понятно, ведь неизвестно же сколько байтов нужно добавлять при каждом шаге чтобы сделать что-то типа s1+1). В общем я в замешательстве
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.08.2011, 14:54     Своя реализация memcpy
Посмотрите здесь:

Memcpy, buffer overflow. Может ли возникнуть ошибка в функции memcpy - C++
Бывает ли на практике такое, что код #define size 1000; // some value int x, y; /* ... */ memcpy(y, x, (size + 1) * sizeof(int)); ...

Своя реализация new - C++
Приведите пожалуйста пример своей реализации operator new и его последующее применение в виде работающей программы, просто хотелось бы...

Своя реализация strtok - C++
Здравсвуте. Пробовал делать поиск, но почему-то все время просто выдает темы где пишет что такая функция есть. Моя же задача - не используя...

Своя реализация strcpy - не пойму где ошибка! - C++
void copy(char *p, char *q) throw (char*) { int l2 = strlen(q); //cout<<"strlen(q)="<<strlen(q)<<" strlen(p)="<<strlen(p)<<endl; ...

memset, memcpy - C++
Использую MSVS 2008. Почему memcpy работает только с char? То есть, такой код работает: int main() { char a1 = "123"; ...

Не работает memcpy - C++
Нужно просто полностью скопировать первый массив, во второй, длина у них одинакова. Делаю так: BYTE in; // = {10, ...} типа заполнен...

2d ---> 1d array и memcpy - C++
Можно ли сконвертировать двумерный массив в одномерный с помощью memcpy? Если да, то будет ли быстрее, чем тупое перебирание в циклах?

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
LosAngeles
Заблокирован
01.08.2011, 15:12     Своя реализация memcpy #2

C++
1
2
3
4
5
6
7
8
template <typename T> T* memcpy(T *s1, T const* s2, size_t n)
{
    for (size_t i = 0; i < n; i++)
    {
        s1[i] = s2[i];
    }
    return s1;
}
Jupiter
Каратель
Эксперт С++
6552 / 3972 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
01.08.2011, 15:13     Своя реализация memcpy #3
надо привести к элементарному типу, вот например, но это не самая лучшая реализация так как копирует по байту
C
1
2
3
4
5
6
7
8
9
10
void* mymemcpy(void* dest, const void* src, size_t bytes)
{
    size_t i;
    char* cdest = (char*)dest;
    const char* csrc = (char*)src;
    for (i = 0; i < bytes; ++i)
        *cdest++ = *csrc++;
    
    return dest;
}
ForEveR
В астрале
Эксперт С++
7968 / 4730 / 320
Регистрация: 24.06.2010
Сообщений: 10,539
Завершенные тесты: 3
01.08.2011, 15:14     Своя реализация memcpy #4
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
 
void* memcpy(void* to, const void* from, size_t n)
{
    const char* f_pointer = (const char*) from;
    char* t_pointer = (char*) to;
    for (size_t i = 0; i < n; ++i)
    {
        *(t_pointer++) = *(f_pointer++);
    }
    return to;
}
 
int main()
{
    int value1 = 10;
    int value2 = 0;
    memcpy(&value2, &value1, sizeof(int));
    std::cout << value2 << '\n';
}
easybudda
Эксперт С++
9456 / 5469 / 927
Регистрация: 25.07.2009
Сообщений: 10,495
01.08.2011, 15:17     Своя реализация memcpy #5
И ещё один хеловорлд
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
 
void * mymemcpy(void * dst, const void * src, size_t cnt){
    unsigned char * d = (unsigned char*)dst;
    const unsigned char * s = (const unsigned char*)src;
    
    while ( cnt-- )
        *d++ = *s++;
    
    return dst;
}
 
void dump(const int * arr, size_t size){
    while ( size-- )
        printf("%d%c", *arr++, ( size ) ? ' ' : '\n');
}
 
#define SIZE 5
int main(void){
    int arr1[SIZE] = { 1, 2, 3, 4, 5 }, arr2[SIZE] = { 0 };
    
    dump(mymemcpy(arr2, arr1, SIZE * sizeof(int)), SIZE);
    
    return 0;
}
xAtom
914 / 739 / 60
Регистрация: 09.12.2010
Сообщений: 1,346
Записей в блоге: 1
01.08.2011, 15:52     Своя реализация memcpy #6
Цитата Сообщение от Maxwe11 Посмотреть сообщение
копирует по байту
Да, по-байту копировать долгий процесс если данных очень много вот накидал копирование двойными словами DWORD
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <stdio.h>
 
void*  _memcpy(void* dst, const void* src, size_t size) {
    void* tmp           = dst;
    unsigned char* _src = (unsigned char*) src;
    unsigned char* _dst = (unsigned char*) dst;
    size_t   len;
    for(len = size / 4u; len--; _src += 4u, _dst += 4u)
       *(size_t*) _dst = *(size_t*) _src;
    len = size % 4u;
    while(len--)
      *_dst++ = *_src++;
    return tmp;
}
 
 
int main(int argc, char* argv[])
{
   int arr[]   = { 12, 23, 45, 55, 22, -50, -5, -4, 900 };
   int dst[9];
   int i;
   char a[]   = "aabb";
   char b[4];
 
   _memcpy(dst, arr, sizeof(arr));
 
   for(i = 0; i < sizeof(dst) / sizeof(int); i++)
        printf("%d, ", dst[i]);
 
 
   puts( (char*) _memcpy(b, a, sizeof(a)) );
 
   getchar();
   return 0;
}
Gepar
1175 / 531 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
01.08.2011, 20:09  [ТС]     Своя реализация memcpy #7
Maxwe11, во ну я что-то такое и хотел, только я сразу в цикле пробовал приводить существующий void к (char*) и оно ругалось.
LosAngeles, это читерство )
Спасибо всем за хелло_ворлды

Хотя возникла ещё одна проблема с похожей функцией, но которая всё сначала копирует себе в временную переменную, а потом уже в нужную переменную
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void *memmove(void *s1, const void *s2, size_t n)
{
    char *s11=(char*)s1;
    char *temp=new char [n+1];
    char *s22=(char*)s2;
    strncpy(temp,s22,n);
    //cout<<"TEST: "<<temp<<endl;
 
    //здесь в цикле почему-то убирается по  первому символу за цикл
    //у каждой переменной, те у temp убирается "abc", а у s11 "sim".
    // почему так? Я же хотел только скопировать "abc" в строку s11
    // вместо sim
    for (size_t i=0;i<n;i++) 
    {
        *(s11++)=*(temp++);
 
    }
    return s11;
}
 
 
int main()
{
    char temp[]="simple";
    cout<<(char*)memmove(temp,"abcde",3);
 
}
Jupiter
Каратель
Эксперт С++
6552 / 3972 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
01.08.2011, 20:21     Своя реализация memcpy #8
Как поместить в массив строк строку
Gepar
1175 / 531 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
01.08.2011, 23:58  [ТС]     Своя реализация memcpy #9
Maxwe11, Вы намекаете на повторное использование strncpy?
Оукей. Но тем не менее мне не понятно почему в моём цикле каждый раз происходил сдвиг начала строки у s11 и temp. Куда же делись первые 3 символа у каждого из указателей

Добавлено через 2 минуты
Хотя strncpy тут использовать не логично, получается как помогалка и всё такое так что я использовал написанную memcpy и получилось вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void *memcpy(void *s1, const void *s2, size_t n)
{
    char *s11=(char*)s1;
    char *s22=(char*)s2;
    for (size_t i=0;i<n;i++)
    {
        *s11++=*s22++;
    }
    return s11;
}
 
void *memmove(void *s1, const void *s2, size_t n)
{
    char *s11=(char*)s1;
    char *temp=new char [n+1];
    char *s22=(char*)s2;
    memcpy(temp,s22,n);
    memcpy(s11,temp,n);
    return s11;
}
 
int main()
{
    char temp[]="simple";
    cout<<(char*)memmove(temp,"abcde",3);
 
}
Но мне всё равно интересно куда подевались символы в моей предыдущей реализации, может кто знает?
grizlik78
Эксперт С++
1903 / 1435 / 109
Регистрация: 29.05.2011
Сообщений: 2,990
02.08.2011, 00:10     Своя реализация memcpy #10
Цитата Сообщение от Maxwe11 Посмотреть сообщение
вот например, но это не самая лучшая реализация так как копирует по байту
А я не согласен и считаю подобную реализацию лучшей. Достаточно взять более-менее оптимизирующий компилятор и он сам развернёт этот цикл, а любые попытки программиста "оптимизировать" чаще всего только мешают оптимизатору, ограничивая его свободу.
Пример работы оптимизатора можно посмотреть здесь. Правда там AT&T синтаксис ассемблера, для многих непривычный.
Jupiter
Каратель
Эксперт С++
6552 / 3972 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
02.08.2011, 00:41     Своя реализация memcpy #11

Не по теме:

Цитата Сообщение от grizlik78 Посмотреть сообщение
более-менее оптимизирующий компилятор
cl.exe с включнной полной оптимизацией к ним не относится)


C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
__declspec(noinline) void* mymemcpy(void* dest, const void* src, size_t bytes)
{
    size_t i;
    char* cdest = (char*)dest;
    const char* csrc = (char*)src;
    for (i = 0; i < bytes; ++i)
//00841000 33 C9                xor         ecx,ecx  
        *cdest++ = *csrc++;
/*
00841002 8A 14 31             mov         dl,byte ptr [ecx+esi]  
00841005 88 14 01             mov         byte ptr [ecx+eax],dl  
00841008 41                   inc         ecx  
00841009 83 F9 14             cmp         ecx,14h  
0084100C 72 F4                jb          mymemcpy+2 (841002h)  
    */
    return dest;
}
 
int main()
{
    int arr[] = { 1, 2, 3, 4, 5 }, arr2[10] = { 0 };
    mymemcpy(arr, arr2, sizeof(arr));
    return 0;
}
grizlik78
02.08.2011, 00:45
  #12

Не по теме:

Цитата Сообщение от Maxwe11 Посмотреть сообщение
cl.exe с включнной полной оптимизацией к ним не относится)
У этого даже комплексное умножение из dll вызывается, если не заставить линковать статически. "Убила бы!". Наверное поэтому стараюсь использовать этот компилятор только для проверки переносимости программ

voral
410 / 390 / 51
Регистрация: 16.03.2008
Сообщений: 1,931
02.08.2011, 01:06     Своя реализация memcpy #13
Цитата Сообщение от Maxwe11 Посмотреть сообщение
но это не самая лучшая реализация так как копирует по байту
Можно воспользоваться кодом, который обсуждали здесь Что делает данный код и зачем такое кому-нибудь может понадобиться?.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void send (int *to, const int *from, int count)
{
  int n = (count + 7) / 8;
  swith (count % 8)
  {
    case 0: do { *to++ = *from++;
    case 7:      *to++ = *from++;
    case 6:      *to++ = *from++;
    case 5:      *to++ = *from++;
    case 4:      *to++ = *from++;
    case 3:      *to++ = *from++;
    case 2:      *to++ = *from++;
    case 1:      *to++ = *from++;
            } while (--n > 0);
  }
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.08.2011, 03:41     Своя реализация memcpy
Еще ссылки по теме:

Как работает memcpy? - C++
Небольшой вопрос по поводу memcpy. Какая из функций будет работать быстрее? typedef unsigned int WORD32; void wcpy(WORD32 * D,...

Объяснить работу Memcpy - C++
Доброго времени суток! Можете пояснить работу memcpy под C++? Что-то у меня определённо работает не так. Например такой код: ...

Memcpy и динамические массивы - C++
Почему значение массива A изменилось? Как этого избежать? int *a = new int ; A = 3; a = 5; int *b = new int ; ...

Насчёт функции memcpy() - C++
Начинаяю использовать эту функцию.Её синтаксис: void memcpy(void *to, const void *from, size_t count); Вопрос_1: Что такое...

Memcpy - вылетает исключение - C++
нужно добавлять в массив по одному элементу и при добавлении нового элемента динамически увеличивать память массива но при копировании...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
03.08.2011, 03:41     Своя реализация memcpy #14
Вот интересно а так было бы пошустрей? Там правда остаток не копируется,но можно доделать побайтно. Я вот только не уверен,как бы это отразилось на скорости,это зависит от внутреннего устройства компилятора?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
/* -------------------------------------------------------------------------- */
void *memcopy(void *dest, const void *const src, size_t n);
/* -------------------------------------------------------------------------- */
void *memcopy(void *dest, const void *const src, size_t n)
{
   long  *temp1 = new long [n];
   void  *temp2 = const_cast<void *> (src);
   size_t count;
 
   if ( (count = n/sizeof(long)) ) {
 
      for (size_t i = 0; i < count; ++i) {
 
         *reinterpret_cast<long *>(temp1)  = *reinterpret_cast<long *>(temp2);
 
         temp2  = reinterpret_cast<long *>(temp2) + 1;
         ++temp1;
      }
 
      temp1 = temp1 - count;
 
      for (size_t i = 0; i < count; ++i) {
 
         *reinterpret_cast<long *>(dest) = *reinterpret_cast<long *>(temp1);
 
         dest  = reinterpret_cast<long *>(dest) + 1;
         ++temp1;
      }
 
      temp1 = temp1 - count;
      dest = reinterpret_cast<long *>(dest)-count;
   }
 
   delete [] temp1;
 
   return dest;
}
/* -------------------------------------------------------------------------- */
int main()
{
    char dest[]="1234567890qwertyuiop";
    char source[]="!@#$%^&*()ASDFGHJKL";
 
    std::cout << "\n" << static_cast<char*>(memcopy(&dest,&source,12)) << "\n";
 
    return 0;
}
/* -------------------------------------------------------------------------- */
Yandex
Объявления
03.08.2011, 03:41     Своя реализация memcpy
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru