无法将短裤复制到动态数组 C++

Posted

技术标签:

【中文标题】无法将短裤复制到动态数组 C++【英文标题】:can't copy shorts into dynamic array C++ 【发布时间】:2013-04-03 13:19:22 【问题描述】:

我一直在尝试将 3d 模型格式加载到 C++ 中,但遇到了问题。一切都很好,除了短裤的索引数组......当我尝试加载一个模型时,数组中的前两个空格是不正确的......如果我加载第二个模型;更多的短裤在模型数据中是错误的......

这是我的头文件:

#ifndef MODELDATA_H
#define MODELDATA_H

#include <GL/glu.h>
#include <string>

using namespace std;


class modelData

    public:
    modelData();
    virtual ~modelData();

    short m_vert_count;
    short m_ind_count;
    short m_tid;
    GLfloat *m_verts;
    GLfloat *m_tex;
    GLint *m_ind;

    void loadModel(string input);
    void draw();

    protected:
    private:
;

#endif // MODELDATA_H

这是我的 cpp 文件:

#include "modelData.h"
#include <GL/glu.h>
#include <fstream>
#include <string.h>
#include <iostream>

using namespace std;

modelData::modelData()

    //ctor
    m_verts = NULL;
    m_tex = NULL;
    m_ind = NULL;
    m_ind_count = 0;
    m_vert_count = 0;


modelData::~modelData()

    //dtor
    delete[] m_verts;
    delete[] m_tex;
    delete[] m_ind;
    m_ind_count = 0;
    m_vert_count = 0;


void modelData::loadModel(string input)

    short temp;
    char *newInput = new char[input.size()+1];
    newInput[input.size()]=0;
    memcpy(newInput,input.c_str(),input.size());
    ifstream a_file( newInput,  ios::binary | ios::in );
    delete newInput;

    a_file.seekg( 0, ios::beg );
    if ( ! a_file.read( reinterpret_cast<char*>( & m_vert_count ), sizeof( short ) ) )
    
        cout << "Error reading from file: can't attain vertex buffer size" << endl;
        return;
    

    if ( ! a_file.read( reinterpret_cast<char*>( & m_ind_count ), sizeof( short ) ) )
    
        cout << "Error reading from file: can't attain index buffer size" << endl;
        return;
    

    m_verts = new GLfloat[m_vert_count];
    m_ind = new GLint[m_ind_count];
    m_tex = new GLfloat[m_vert_count];

    for (int i = 0; i < m_vert_count; i++)
    
        if ( ! a_file.read( reinterpret_cast<char*>( & m_verts[i] ), sizeof( float ) ) )
        
            cout << "Error reading from file: can't attain vertex buffer" << endl;
            return;
        
    

    for (int i = 0; i < ((m_vert_count)/3)*2; i++)
    
        if ( ! a_file.read( reinterpret_cast<char*>( & m_tex[i] ), sizeof( float ) ) )
        
            cout << "Error reading from file: can't attain texcoord buffer" << endl;
            return;
        
    
    for (int i = 0; i < m_ind_count; i++)
    
        if ( ! a_file.read( reinterpret_cast<char*>( & m_ind[i] ), sizeof( short ) ) )
        
            cout << "Error reading from file: can't attain index buffer" << endl;
            return;
        
    


    cout << m_vert_count << "   " << m_ind_count << endl;
    cout << "Model successfully loaded from " << input << "  ...Jolly good." << endl;



void modelData::draw()

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3,GL_FLOAT,0,m_verts);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glTexCoordPointer(2,GL_FLOAT,0,m_tex);
    glDrawElements(GL_TRIANGLES,m_ind_count,GL_UNSIGNED_INT,m_ind);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);


我希望代码不要太长或太乱,我真的不知道发生了什么……据我所知; m_verts[] 和 m_tex[] 看起来填充得很好,但是 m_ind[] 不断地通过数组弹出错误的数字......我是否错误地分配了数组?我没有清理我应该清理的东西吗?

哦,我不认为这是导致问题的原因,但您会注意到我没有添加任何东西来进行大端或小端转换......这是因为我使用的是英特尔机器,看起来总是假设 little endian 而我的 android 游戏引擎使用 little endian...所以我认为这不是问题...

任何帮助或建议都会很棒。 感谢阅读。

【问题讨论】:

GLint 的大小是否与short 相同?为什么使用sizeof( short ) 为什么不使用sizeof( GLint) 这不能回答你的问题,但在 loadModel 中,整个 newInput 应该替换为 ifstream a_file( input.c_str(), ios::binary | ios::in );(或者,在 C++11 中,ifstream a_file( input, ios::binary | ios::in );)。 请将您自己(和我们)从手动内存管理中解放出来,使用std::vector 或标准库中更合适的方式,并遵守三/五规则(_you have many potential memory leaks and double有删减)。此外,将您自己(和我们)从头文件中的全局 using 指令中解放出来。即,在尝试做更高级的事情之前,先找一本讲授惯用 C++ 的好 C++ 书籍。 @stardust_ 实际上该格式使用短裤,但您和 Angew 的 cmets 提供了帮助,因为这被证明是问题所在......我刚刚将 short 转换为 GLint,现在代码运行良好。 【参考方案1】:

如果我没看错的话,m_ind 被键入为 GLints 的数组,但您正在读取它,就好像它是 shorts 的数组一样。在大多数平台上,这意味着值的前两个字节几乎是随机的。

如果您的数据流实际上包含短裤,这将是读取它们的安全方法:

for (int i = 0; i < m_ind_count; i++)

    short val;
    if ( ! a_file.read( reinterpret_cast<char*>( & val ), sizeof( short ) ) )
    
        cout << "Error reading from file: can't attain index buffer" << endl;
        return;
    
    m_ind[i] = val;

一些不相关的注释:

o这个:

char *newInput = new char[input.size()+1];
newInput[input.size()]=0;
memcpy(newInput,input.c_str(),input.size());
ifstream a_file( newInput,  ios::binary | ios::in );
delete newInput;

这只是一种非常复杂的说法:

ifstream a_file(input.c_str(), ios::binary | ios::in);

o 我强烈建议使用std::vector,而不是手动动态分配和释放数组。

【讨论】:

感谢您这么快回复。关于字符串到字符转换的第二点非常有帮助。不幸的是,被读入以填充 m_ind 的二进制文件实际上是由短裤组成的……问题可能是使用 ifstream 将一个短裤复制到 GLint 中吗?由于某些奇怪的原因,大多数短裤都可以很好地复制,但有些则变成了非常大的数字,例如“131258”。 非常感谢。我想我去年对使用 Java 感到困惑...我认为我编写的 Java 版本自动将 short 转换为 Ints...感谢 std::vector 的建议,我可能会使用它而不是未来的动态数组。

以上是关于无法将短裤复制到动态数组 C++的主要内容,如果未能解决你的问题,请参考以下文章

输出没有重复元素的动态数组(缩小数组)C++

C++ 动态数组 - 为啥我能做到这一点? [复制]

将二维数组复制到函数外部动态分配的二维数组

为啥必须动态分配扩展数组才能使此函数正常工作 C++

是否可以在不重新分配的情况下实现动态数组?

C++动态申请数组问题