Операция memcpy () над целочисленными массивами в конструкторе дает неожиданный вывод в C ++ - PullRequest
0 голосов
/ 29 марта 2012

Я знаю, что мог бы использовать std :: vector в C ++ вместо массивов и избавить меня от некоторых проблем.Однако этот вопрос не для практического применения.Это скорее для моего понимания.Я вижу «0» вместо фактического значения в операции memcpy ().Что я делаю не так в этом тестовом коде?

#include <stdint.h>
#include <cstring>
#include <cstdlib>
#include <iostream>

using namespace std;

class IntList
{
private:
     int* m_anList; //I could use std::vector in practical applications I know
                    //However I want to experiment what happens

public:
       IntList(const int m_anList[]){ 
       this->m_anList = new int[sizeof(m_anList+1)]; //heap allocation - since bad idea to copy on stack

       memcpy((int*)this->m_anList,m_anList,sizeof(m_anList+1)); //<-This does not look right
       cout << this->m_anList[4] << endl;//<- gives '0'??? Not expected

       }
     ~IntList(){
      if(this->m_anList)
      {
       delete[] this->m_anList; 
      }
     }

     int& operator[] (const int& nIndex);
};

int& IntList::operator[] (const int& nIndex)
{
    cout << this->m_anList[nIndex] << endl; //<- gives '0'??? Not Expected
    return this->m_anList[nIndex];
}


int main()
{

   int test_array[10] = {1,2,3,4,5,6,7,8,9};

   IntList test(test_array);

   test[2];      

   return 0;
}

Я использовал его на char * раньше, и это сработало.char = 1 байт, int = 2 байта, но memcpy применяется к void *.

Обновлен код / ​​решение (спасибо Робу (который указал на мою самую фундаментальную из нескольких ошибок) и всемЯ не CS выпускник, но буду пытаться писать лучше в будущем. Еще раз спасибо.)

#include <stdint.h>
#include <cstring>
#include <cstdlib>
#include <iostream>
//#include <algorithm>
//#include <vector>

using namespace std;

class IntList
{
private:
     int* m_anList; //I could use std::vector in practical applications I know
                    //However I want to experiment what happens

public:
      IntList(const int m_anList[], std::size_t n){ 
      this->m_anList = new int[n * sizeof(int)];
      memcpy(this->m_anList,m_anList,n*sizeof(m_anList[0]));
      cout << this->m_anList[4] << endl;     
     }
     ~IntList(){
      if(this->m_anList)
       delete[] this->m_anList;
     }

     int& operator[] (const int& nIndex);
};

int& IntList::operator[] (const int& nIndex)
{
    cout << this->m_anList[nIndex] << endl;  
    return this->m_anList[nIndex];
}


int main()
{

   int hello[10] = {1,2,3,4,5,6,7,8,9};

   //cout << hello[3] << endl;

   IntList test(hello,10);

   test[2];


 return 0;
}

Ответы [ 5 ]

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

sizeof(m_anList+1) не делает то, что вы думаете, что делает. В частности, оно идентично sizeof(int*). Следовательно, вы выделяете (обычно) четыре или восемь байтов в выражении new, а не размер переданного массива.

Для того, чтобы это работало, вы также должны передать размер массива:

   IntList(const int m_anList[], std::size_t n){ 
     this->m_anList = new int[n];
     memcpy(this->m_anList,m_anList,n*sizeof(m_anList[0]));
     …
2 голосов
/ 29 марта 2012

В коде очень много ошибок, включая

  • броски в стиле C

  • sizeof указатель

  • с использованием memcpy вместо std::copy

Единственное исправление невозможно.

1 голос
/ 29 марта 2012

В C ++ при объявлении функции, принимающей параметр с использованием «синтаксиса массива»

void foo(int v[])
{
    ...
}

вы действительно просто объявляете функцию, принимающую указатель.Другими словами, вышеприведенное абсолютно идентично

void foo(int *v)
{
    ...
}

, а sizeof(v) - это размер указателя, а не размер массива.

Сделайте себе одолжение и прекратите просто пытатьсяизучить C ++, экспериментируя с компилятором.С языком C ++ такой подход является полным самоубийством.

Вместо этого начните с хорошей книги по C ++ и читайте от корки до корки ... это единственный способ.

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

Вы должны поставить +1 вне sizeof ().

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

Память, выделенная с помощью new, не запоминает свой собственный размер.Вы должны держать его в стороне в своем собственном целом числе и использовать ТО для выделения и копирования памяти.Ваше выражение sizeof просто получит число байтов в указателе.

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

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

...