0

課題として単純なベクトル プログラムに取り組んでいますが、プログラムが主張する理由がわかりません。プログラムは正常にコンパイルされますが、実行時に失敗します。私はこれについて専門知識の範囲にいると思います。

#include <iostream>
#include <cstring>
#include <assert.h>
#include <stdio.h>
#include <iomanip>
#define TESTING
using namespace std;
typedef float Elem;//floats for vector elements

struct Vector{//structure for the vector
    unsigned int size;
    Elem *svector;
};


int main(){

#ifdef TESTING
        //prototypes
    Vector *alloc_vec();
    bool print_vec(Vector *printVector);
    Vector *extend_vec(Vector *extend,Elem element);
    Vector *scalar_plus(Vector *vecToAdd, Elem addElement);
    void dealloc_vec(Vector *&deAlloc);

    //testing scaffolds
    Vector *testVec=new Vector;
    *testVec=*alloc_vec();
    assert(testVec->size==0);
    assert(testVec->svector==NULL);

    for(int i=0;i=10;i++){
        *testVec=*extend_vec(testVec,Elem(i));
    }

    assert(testVec->size!=0);
    assert(testVec->svector!=NULL);

    assert(print_vec(testVec));
    print_vec(testVec);

    *testVec=*scalar_plus(testVec,5);

    print_vec(testVec);

    dealloc_vec(testVec);

    assert(testVec==NULL);
#endif //testing

    return 0;
}

Vector *alloc_vec(){//constructor to allocate an empty (zero-length) vector
    Vector *newVector=new Vector; //initiatizes a new vector
        if (newVector==NULL){
        return NULL;
    }

    newVector->size=0;//sets length to 0 
    newVector->svector=NULL;//sets vector to null


    return newVector;
}

bool print_vec(Vector *printVector){

    if(printVector==NULL){//makes sure printVector exists to pass unit test 1
        return false;
    }

    for(unsigned int i=0; i<printVector->size;i++){
        cout<<printVector->svector[i]<<endl;
    }

    return true;

}

void dealloc_vec(Vector *deAlloc){
    if (deAlloc==NULL){//if the vector contains no memory, no need to deallocate, unit test#1
        return;}

    delete deAlloc;//clears the memory of the vector
    deAlloc=NULL;
    return;

}

Vector *extend_vec(Vector *extend,Elem element){
    if (extend==NULL){
        return NULL;}


    Elem *tempVec=new Elem[extend->size+1];//sets up a temp vector one size larger
    tempVec[extend->size]=element;

    memcpy(tempVec,extend->svector,(extend->size*sizeof(Elem)));//copies the memory from the original array to the rest of the temp array

        extend->size+=1;

    delete[] extend->svector;//clears the memory

    extend->svector=tempVec;//the original vector now becomes the extended vector

    delete[] tempVec;//clears the temporary memory

        return extend;
}

Vector *scalar_plus(Vector *vecToAdd, Elem addElement){
    if (vecToAdd==NULL){
        return NULL;}
    for(unsigned int i=0;i<vecToAdd->size;i++){//adds a scalar to each element 
        vecToAdd->svector[i]+=addElement;
        }

        return vecToAdd;
}

**EDIT何人かの人々が私が得たアサーションエラーを私に尋ねました:

デバッグ アサーションに失敗しました!

プログラム: ...12\Projects\ConsoleApplication2\Debug\ConsoleApplication2.exe

ファイル:f:\dd\vctools\crt_bld\self_x86\crt\src\dggdel.cpp

ライン:52

式:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

次の変更も行いました: assert(testVec=NULL) (deAlloc==NULL)

assert(testVec==NULL)
(deAlloc==NULL)

この関数から: void dealloc_vec(Vector *deAlloc)

に:

void dealloc_vec(Vector *&deAlloc)

アサーション エラーは修正されましたが、出力は生成されません。引き続きデバッグに取り組んでいます。

また、これは C++ よりも C に近い可能性があります。私の教授は課題仕様書でこれは C++ であると述べていますが、彼は私たちのクラスの 2 つのロットを切り替えます。

4

1 に答える 1

6
assert(testVec=NULL);

ブール値として扱われる場合は false であるその null ポインターに設定testVecNULLれ、等しいと評価されます。

それはほぼ確実にassert(testVec == NULL);代わりになるはずです。

今後の参考のために、これが、定数と比較するときに C および C++ で(NULL == testVecではなく)いわゆる「Yoda 条件」が好まれる理由です。の代わりtestVec == NULLに誤って使用すると、 Yoda 条件はコンパイルに失敗し、問題がより明白になります。===

それを修正すると、別の問題が発生 しますdealloc_vec。. Vector*変更は呼び出し元に戻りません。Vector*&(ポインターへの参照)を取る関数を宣言することができます。ただし、それを行う前に、修正する別の比較ではなく割り当てが if (dealloc=NULL)ありますif (dealloc == NULL)

さらに、delete[] tempvec;inextend_vecはまだ使用しているメモリを解放します。そのままにしておくと、セグメンテーション違反とヒープの破損が発生します。だからそれを削除します。

于 2012-11-03T01:44:14.990 に答える