gpt4 book ai didi

c++ - 从此指针复制后尝试访问基类的成员时出现段错误

转载 作者:行者123 更新时间:2023-11-30 04:18:52 25 4
gpt4 key购买 nike

我要提前为庞大的代码块道歉——我已尽力将其简化为测试用例。

我的程序在 vectorTest.cpp 中抛出段错误, 在标有注释的行上。我一直追踪段错误到内部 Matrix.h::Matrix< T >::operator[] ,如那里的评论所示。

问题似乎是我无法访问O.rref()::rrefMatrix._values .这很奇怪,因为你可以从 vectorTest.cpp 的其余部分看到, 我访问 M._values 没问题, M.rref()::rrefMatrix._values , 或 O._values .只有当我使用 append() Matrix< T >::rref() 函数后跟我遇到了我的错误。

我快要穷途末路了。有人可以给我一个解释吗?

vectorTest.cpp:

#include "Vector.h"
#include "Polynomial.h"
#include "Matrix.h"

#include <iostream>

using namespace std;

int main( int argc, char* argv[] )
{
Matrix< float > M( 3, 3 );
M.setValues( { 1, 2, 3, 4, 5, 6, 7, 8, 8 } );

cout << M << endl;

cout << M.rref() << endl;

Matrix< float > N( 3, 1 );
N.setValues( { 2, -2, 5 } );

Matrix< float > O = append( M, N );

cout << O << endl;

cout << O.rref() << endl; //Segfault!

return 0;
}

矩阵.h:

#ifndef __INCL_MATRIX_H__
#define __INCL_MATRIX_H__

#include "Vector.h"
#include <iterator>
#include <algorithm>
#include <utility>
#include <initializer_list>
#include <type_traits>
#include <iomanip>
#include <sstream>
#include <cassert>

template < class T >
class Matrix
: Vector< T >
{
public:
Matrix() :
Vector< T >::Vector()
{};
Matrix( const Matrix< T >& cMatrix ) :
Vector< T >::Vector( cMatrix ),
_numRows( cMatrix._numRows ),
_numColumns( cMatrix._numColumns )
{};
Matrix( const unsigned int r, const unsigned int c ) :
_numRows( r ),
_numColumns( c )
{
_values.reserve( r * c );
for( unsigned int r = 0; r < _numRows; r++ )
for( unsigned int c = 0; c < _numColumns; c++ )
_values[ r * _numColumns + c ] = T( 0 );
}

Matrix< T >& operator= ( const Matrix< T >& );

template < class InputIterator >
typename std::enable_if< std::is_same< T, typename std::iterator_traits< InputIterator >::value_type >::value, void >::type
setValues( InputIterator, InputIterator );

void setValues( std::initializer_list< T > );

T* operator[] ( const unsigned int );
const T* operator[] ( const unsigned int ) const;

unsigned int numRows() const;
unsigned int numColumns() const;

Matrix< T > rref() const;

protected:
void swapRows( const unsigned int, const unsigned int );

private:
using Vector< T >::_values;

unsigned int _numRows;
unsigned int _numColumns;
};


template < class T >
Matrix< T >& Matrix< T >::operator= ( const Matrix< T >& cMatrix )
{
_numRows = cMatrix._numRows;
_numColumns = cMatrix._numColumns;
_values = cMatrix._values;

return *this;
}

template < class T >
template < class InputIterator >
typename std::enable_if< std::is_same< T, typename std::iterator_traits< InputIterator >::value_type >::value, void >::type Matrix< T >::setValues( InputIterator begin, InputIterator end )
{
_values.clear();
for( auto it = begin; it != end; it++ )
if( _values.size() < _numRows * _numColumns )
_values.push_back( *it );
}

template < class T >
void Matrix< T >::setValues( std::initializer_list< T > iList )
{
setValues( iList.begin(), iList.end() );
}

template < class T >
T* Matrix< T >::operator[] ( const unsigned int r )
{
return &( _values[ r * _numColumns ] ); //This is the thorn in my paw.
}

template < class T >
const T* Matrix< T >::operator[] ( const unsigned int r ) const
{
return &( _values[ r * _numColumns ] );
}

template < class T >
unsigned int Matrix< T >::numRows() const
{
return _numRows;
}

template < class T >
unsigned int Matrix< T >::numColumns() const
{
return _numColumns;
}

template < class T >
constexpr T abs( const T a )
{
return ( a < 0 ) ? -a : a;
}

template < class T >
constexpr T gcd( const T a, const T b )
{
return ( a == b || b == 0 ) ? a : ( ( a < b ) ? gcd( abs( b ), abs( a ) ) : gcd( abs( a ) - abs( b ), abs( b ) ) );
}

template < typename T, typename... Ts >
constexpr T gcd( const T a, const T b, const Ts... others )
{
return gcd( gcd( a, b ), others... );
}

template < class T >
Matrix< T > Matrix< T >::rref() const
{
Matrix< T > rrefMatrix = (*this);
unsigned int p = rrefMatrix._numColumns;
T mult = 0, mult1 = 0, mult2 = 0;

for( unsigned int r1 = 0; r1 < rrefMatrix._numRows; r1++ )
{
p = rrefMatrix._numColumns;
for( unsigned int r2 = r1; r2 < rrefMatrix._numRows; r2++ )
{
for( unsigned int c = 0; c < rrefMatrix._numColumns; c++ )
{
if( rrefMatrix[r2][c] != T( 0 ) ) // Why is this segfaulting?
{
p = c;
break;
}
}
if( p != rrefMatrix._numColumns )
{
if( r2 > r1 )
{
rrefMatrix.swapRows( r1, r2 );
}
break;
}
}
if( p == rrefMatrix._numColumns )
break;

for( unsigned int r2 = 0; r2 < rrefMatrix._numRows; r2++ )
{
if( r1 == r2 ) continue;

mult = gcd( rrefMatrix[r1][p], rrefMatrix[r2][p] );

mult1 = mult * rrefMatrix[r2][p];
mult2 = mult * rrefMatrix[r1][p];

for( unsigned int c = 0; c < rrefMatrix._numColumns; c++ )
{
rrefMatrix[r1][c] *= mult1;
rrefMatrix[r2][c] *= mult2;
}

for( unsigned int c = 0; c < rrefMatrix._numColumns; c++ )
{
rrefMatrix[r2][c] -= rrefMatrix[r1][c];
rrefMatrix[r1][c] /= mult1;
}
}
}

for( unsigned int r = 0; r < rrefMatrix._numRows; r++ )
{
p = _numColumns;
for( unsigned int c = 0; c < rrefMatrix._numColumns; c++ )
{
if( rrefMatrix[r][c] != 0 )
{
p = c;
break;
}
}

if( p == rrefMatrix._numColumns ) continue;

mult = rrefMatrix[r][p];

for( unsigned int c = 0; c < rrefMatrix._numColumns; c++ )
rrefMatrix[r][c] /= mult;
}

return rrefMatrix;
}

template < class T >
void Matrix< T >::swapRows( const unsigned int r1, const unsigned int r2 )
{
for( unsigned int c = 0; c < _numColumns; c++ )
std::swap( (*this)[r1][c], (*this)[r2][c] );
}

template < class T >
unsigned int strLength( T& item )
{
std::stringstream ss;
ss << item;
return ss.str().length();
}

template < class T >
std::ostream& operator<< ( std::ostream& out, const Matrix< T >& cMatrix )
{
unsigned int maxLength = 0, currLength = 0;

for( unsigned int r = 0; r < cMatrix.numRows(); r++ )
for( unsigned int c = 0; c < cMatrix.numColumns(); c++ )
{
currLength = strLength( cMatrix[r][c] );
if( currLength > maxLength )
maxLength = currLength;
}

for( unsigned int r = 0; r < cMatrix.numRows(); r++ )
{
for( unsigned int c = 0; c < cMatrix.numColumns(); c++ )
out << std::setw( maxLength ) << cMatrix[r][c] << ' ';
out << std::endl;
}

return out;
}

template < class T >
Matrix< T > append( const Matrix< T >& lhs, const Matrix< T >& rhs )
{
Matrix< T > appendMatrix( lhs.numRows(), lhs.numColumns() + rhs.numColumns() );

for( unsigned int r = 0; r < appendMatrix.numRows(); r++ )
{
for( unsigned int c = 0; c < lhs.numColumns(); c++ )
{
appendMatrix[r][c] = lhs[r][c];
}

for( unsigned int c = 0; c < rhs.numColumns(); c++ )
{
appendMatrix[r][ c + lhs.numColumns() ] = rhs[r][c];
}
}

return appendMatrix;
}

#endif

vector .h:

#ifndef __INCL_VECTOR_H__
#define __INCL_VECTOR_H__

#include <vector>
#include <iostream>
#include <iterator>
#include <initializer_list>
#include <type_traits>
#include <assert.h>

struct VectorBase {};

template < class T >
class Vector
: public VectorBase
{
public:
Vector()
{};
Vector( const Vector< T >& cVector ) :
_values( cVector._values )
{};
template < class InputIterator >
Vector( InputIterator first, InputIterator last ) :
_values( first, last )
{};
Vector( std::initializer_list< T > iList ) :
_values( iList.begin(), iList.end() )
{};

protected:
std::vector< T > _values;
};

#endif

输出:

1 2 3 
4 5 6
7 8 8

1 -0 -0
-0 1 -0
0 0 1

1 2 3 2
4 5 6 -2
7 8 8 5

Segmentation fault (core dumped)

最佳答案

在这个构造函数中:

Matrix( const unsigned int r, const unsigned int c ) :
_numRows( r ),
_numColumns( c )
{
_values.reserve( r * c );
for( unsigned int r = 0; r < _numRows; r++ )
for( unsigned int c = 0; c < _numColumns; c++ )
_values[ r * _numColumns + c ] = T( 0 );
}

改变这个:

        _values.reserve( r * c );

对此:

        _values.resize( r * c );

请参阅 std::vector<>::reserve() 的文档为什么。它设置容量;不是尺寸。这只是意味着您可以将 vector 增长到规定的容量,而不会触发内部重新分配和潜在的对象被复制。

注意:我会认真考虑重组以构造基于rc 的预定大小的 vector 。

关于c++ - 从此指针复制后尝试访问基类的成员时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16128683/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com