在另一个函数中传递一个三重指针来分配内存,sscanf异常

Passing a triple pointer to allocate memory in another function, sscanf exception

本文关键字:指针 三重 分配 异常 sscanf 内存 一个 函数 另一个      更新时间:2023-10-16

我在另一个函数中分配内存给双指针,因此我需要使用指针指向指针的指针。当我使用sscanf时,我得到一个异常抛出,我不确定确切的原因。下面是代码片段。这是工作的早期,当它都在同一个函数,我只需要使用双指针,但现在,我重构代码和使用三重指针,我有这个问题。

typedef float vector[3]
int mainLoaderFunc() {
    char* memory = NULL;
    size_t size = loadFile(fileName, &memory); // load model file into memory, this works, tested and true
    // create vector arrays
    vector *vertexArray = NULL;         
    vector *normalArray = NULL;         
    vector *textureArray = NULL;        
    loadArrays(size, memory, &vertexArray, &normalArray, &textureArray);
    // do other stuff with arrays
}
void loadArrays(size_t size, char *memory, vector **vertexArray, vector **normalArray, vector **textureArray) {
    int numVerts = 0; 
    int numNormals = 0;  
    int numTextures = 0;  
    char* p = memory;           // pointer to start of memory
    char* e = memory + size;    // pointer to end of memory
    // count verts, normals, textures for memory allocation
    while (p != e) {
        if (memcmp(p, "vn", 2) == 0) {
            numNormals++;
        } else if (memcmp(p, "vt", 2) == 0) { 
            numTextures++;
        } else if (memcmp(p, "v",  1) == 0) {
            numVerts++;
        } 
        while (*p++ != (char) 0x0A);
    }
    // allocate memory for vector arrays
    *vertexArray        = new vector[numVerts];
    *normalArray        = new vector[numNormals];
    *textureArray       = new vector[numTextures];
    p = memory;
    int vertexIndex = 0;
    int normalIndex = 0;
    int textureIndex = 0;  //*** IF BREAK POINT HERE: NO EXCEPTION
    // load data from memory into arrays
    while (p != e) {
        if (memcmp(p, "vn", 2) == 0) {
            sscanf(p, "vn %f %f %f", &normalArray[normalIndex][0], &normalArray[normalIndex][1], &normalArray[normalIndex][2]);
            normalIndex++;
        } else if (memcmp(p, "vt", 2) == 0) {
            sscanf(p, "vt %f %f", &textureArray[textureIndex][0], &textureArray[textureIndex][1]);
            textureIndex++;
        } else if (memcmp(p, "v", 1) == 0) {
            sscanf(p, "v %f %f %f", &vertexArray[vertexIndex][0], &vertexArray[vertexIndex][1], &vertexArray[vertexIndex][2]);
            vertexIndex++;
        } 
        while (*p++ != (char) 0x0A);
    }
}

一旦代码到达sscanf部分,我得到异常:

Unhandled exception at 0x5e9cf2dc (msvcr100d.dll) in derp.exe: 0xC0000005: Access violation writing location 0xcccccccc.

您正在向sscanf传递无效地址。查看函数的一个参数:

vector **vertexArray

vertexArray指向从mainLoaderFunc传入的指针的地址。*vertexArray指的是指向实际vector数组的指针,当您为它分配内存时,您会意识到这一点:

*vertexArray = new vector[numVerts];

因此数组中的有效元素应该是:

(*vertexArray)[vertexIndex][0]

注意你的代码缺少的*;*vertexArray为实际阵列。现在sscanf需要这个变量的地址,所以现在得到它的地址(为了清晰起见,添加了额外的括号):

&( (*vertexArray)[vertexIndex][0] )

sscanf的所有参数都改成这样

正如有人指出的,你真的不应该在这里使用三重指针。

此外,您可能希望将文件扫描作为链式if块(或至少将其拆分为函数)以外的东西进行。

这应该解决你的问题,因为你只有2个引用,你应该有3个:

    if (memcmp(p, "vn", 2) == 0) {
        sscanf(p, "vn %f %f %f", &(*normalArray)[normalIndex][0], &(*normalArray)[normalIndex][1], &(*normalArray)[normalIndex][2]);
        normalIndex++;
    } else if (memcmp(p, "vt", 2) == 0) {
        sscanf(p, "vt %f %f", &(*textureArray)[textureIndex][0], &(*textureArray)[textureIndex][1]);
        textureIndex++;
    } else if (memcmp(p, "v", 1) == 0) {
        sscanf(p, "v %f %f %f", &(*vertexArray)[vertexIndex][0], &(*vertexArray)[vertexIndex][1], &(*vertexArray)[vertexIndex][2]);
        vertexIndex++;
    } 

当将向量指针传递给sscanf()时,您没有正确地解引用它们。试试这个:

if (memcmp(p, "vn", 2) == 0) { 
    sscanf(p, "vn %f %f %f", &((*normalArray)[normalIndex][0]), &((*normalArray)[normalIndex][1]), &((*normalArray)[normalIndex][2])); 
    ++normalIndex; 
} else if (memcmp(p, "vt", 2) == 0) { 
    sscanf(p, "vt %f %f", &((*textureArray)[textureIndex][0]), &((*textureArray)[textureIndex][1])); 
    ++textureIndex; 
} else if (memcmp(p, "v", 1) == 0) { 
    sscanf(p, "v %f %f %f", &((*vertexArray)[vertexIndex][0]), &((*vertexArray)[vertexIndex][1]), &((*vertexArray)[vertexIndex][2])); 
    ++vertexIndex; 
}