2012-04-10 3 views
2

В настоящее время я получаю «0xC0000005: место обнаружения нарушения доступа 0xcccccce0». ошибка, и я попытался диагностировать проблему ... Я думаю, что проблема возникает, когда мое правило 3, которое я определил, входит в игру и указывает на меня.Ошибка чтения C++ Read Access

size_type size() const 
    { // return length of sequence 
    return (this->_Mysize); <---------------------this line 
    } 

Я на самом деле не уверен, что если есть какие-либо проблемы вообще, я останавливаться на этом в течение нескольких дней подряд.

Ниже мое правило три

ArrayStorage::ArrayStorage(){ 
    myArray = new string[7079]; 
} 

ArrayStorage::~ArrayStorage(){ 
    delete[] _data; 
    delete[] myArray; 
} 

ArrayStorage::ArrayStorage(const ArrayStorage &A) { 
    _size = A.size(); 
    _data = new string [size()]; 
    for (int i = 0; i < size(); ++i) 
     _data[i] = A[i]; 
} 

ArrayStorage& ArrayStorage::operator=(const ArrayStorage &A){ 
    if (this != &A) { 
     delete [] _data; 
     _size = A.size(); 
     _data = new string [A.size()]; 
     for (int i = 0; i < size(); ++i) { 
      _data[i] = A[i]; 
     } 
    } 
    return *this; 
} 

const string& ArrayStorage::operator[](int i) const{ 
    assert((i >= 0) && (i < size())); 
    return _data[i]; 
} 

string& ArrayStorage::operator[](int i){ 
    assert((i >= 0) && (i < size())); 
    return _data[i]; 
} 
+2

трассировку бы полезно здесь – daramarak

+1

Вы проверили, что 'this' действует? У вас есть обратная связь от отладчика (вы проверяли приложение в отладчике?)? И почему вы пытаетесь реализовать свой собственный «массив» вместо использования каких-либо стандартных контейнеров, таких как 'std :: vector'? –

+0

Я бы предположил, что это проблема с указателем, но невозможно сказать без stacktrace/backtrack. Где-то вы вызываете size() в адресе, где вы думаете, что есть ArrayStorage, но нет. Поскольку это 0xccccce0, я бы пошел с унифицированным указателем. – dutt

ответ

5

Когда неинициализированные переменные стека заполняются байтами 0xCC, если они скомпилированы с msvc. Таким образом, 0xcccccce0, вероятно, является результатом «этого», являющегося неинициализированной переменной указателя в стеке плюс смещение _MySize в структуре объекта.

+1

Это хороший совет. Может ли он определить «ArrayStorage *», а не инициализировал его «новым»? –

+0

Скорее всего. Если компилятор оптимизирует код и использует метод inline, size() преобразуется в прямой доступ к полям, минуя vtable и приводя к этому нарушению доступа. –

+0

Что такое vtable? Я не видел ничего, что могло бы заставить меня поверить, что «размер» - это виртуальная функция. –

0

Breakpoints/наблюдения. Я предполагаю, что это является null.

1

Есть целый ряд очевидных проблем с кодом: ваш деструктор, , например, делает delete [] _data и delete [] myArray, но _data никогда не инициализируется в конструкторе по умолчанию, и myArray никогда не инициализируется в конструкторе копирования , И вы назначаете оператор может оставить объект в недопустимом состоянии, если, например, new не работает. (В общем, если вам нужно проверить самоопределение, то почти наверняка будет нарушен ваш оператор присваивания.) Либо из эти проблемы приводят к неопределенному поведению, которое может повредить бесплатную космическую арену , в результате чего кто-нибудь знает, в чем проблема.

Тем не менее, было бы интересно посмотреть, где был вызван size. Сообщение об ошибке указывает на недопустимое значение this; что вы вызвали функцию с недопустимым адресом.

0

Я бы предположил, что это проблема с указателем, но невозможно сказать без stacktrace/backtrack. Где-то вы вызываете size() в адресе, где вы думаете, что есть ArrayStorage, но нет. Поскольку это 0xccccce0, я бы пошел с унифицированным указателем.

Например, у вас есть что-то вроде этого

ArrayStorage storage1; 
ArrayStorage* storage2; 
*storage2 = storage1; 

Это приведет к тому или подобной ошибки, утратившим этот указатель.

И почему вы пишете свой собственный std :: vector?

+0

Ваш второй пример не будет компилироваться; вы не можете определить ссылку без инициализатора. –

+0

Спасибо, удалил. – dutt