什么原因导致堆栈溢出?

问题描述 投票:0回答:1

我一直在关注 this 文章,该文章创建了一个二十面体并将其细分为一个 icosphere 以用于我正在制作的游戏,我决定尝试从 C# 移植到 C。但是当我完成所有代码的移植后,我遇到了这个错误

Process returned -1073741795 (0xC000001D)   execution time : 8.057 s Press any key to continue.
,在使用 print 语句和 gdb 帮助处理了几个小时后,我似乎无法修复该错误。这是我的代码的相关片段


#include <stdio.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>

typedef struct Point3D
{
    double x;
    double y;
    double z;
} point3D;

typedef struct Triangleindices
{
    int v1;
    int v2;
    int v3;
} triangles;

typedef struct MeshGeometry3D
{
    point3D *positions;
    int *triangle_indices;
} mesh_geometry;

typedef struct IcosphereCreator
{
    mesh_geometry geometry;
    int index;
    int *cache;
} icosphere;

int add_vertex(icosphere* creator, point3D p)
{
    double length = sqrt(p.x * p.x + p.y * p.y + p.z * p.z);
    creator->geometry.positions[creator->index].x = p.x / length;
    creator->geometry.positions[creator->index].y = p.y / length;
    creator->geometry.positions[creator->index].z = p.z / length;
    return creator->index++;
}

int get_middle_point(icosphere* creator, int p1, int p2)
{
    bool first_is_smaller = p1 < p2;
    int64_t smaller_index = first_is_smaller ? p1 : p2;
    int64_t greater_index = first_is_smaller ? p2 : p1;
    int64_t key = (smaller_index << 32) + greater_index;

    if (creator->cache[key] != 0)
    {
        return creator->cache[key];
    }

    point3D point1 = creator->geometry.positions[p1];
    point3D point2 = creator->geometry.positions[p2];
    point3D middle;
    middle.x = (point1.x + point2.x) / 2.0;
    middle.y = (point1.y + point2.y) / 2.0;
    middle.z = (point1.z + point2.z) / 2.0;

    int i = add_vertex(creator, middle);
    return i;
}

mesh_geometry create_icosphere(icosphere* creator, int subdivide)
{
    int max_triangles = 20 * (1 << (2 * subdivide));
    long long unsigned int array_size = max_triangles * sizeof(triangles);

    creator->geometry = (mesh_geometry){0};
    mesh_geometry result = (mesh_geometry){0};
    creator->index = 0;

    point3D p1 = {-1, (1.0 + sqrt(5.0)) / 2.0, 0};
    point3D p2 = {1, (1.0 + sqrt(5.0)) / 2.0, 0};
    point3D p3 = {-1, -(1.0 + sqrt(5.0)) / 2.0, 0};
    point3D p4 = {1, -(1.0 + sqrt(5.0)) / 2.0, 0};
    point3D p5 = {0, -1, (1.0 + sqrt(5.0)) / 2.0};
    point3D p6 = {0, 1, (1.0 + sqrt(5.0)) / 2.0};
    point3D p7 = {0, -1, -(1.0 + sqrt(5.0)) / 2.0};
    point3D p8 = {0, 1, -(1.0 + sqrt(5.0)) / 2.0};
    point3D p9 = {(1.0 + sqrt(5.0)) / 2.0, 0, -1};
    point3D p10 = {(1.0 + sqrt(5.0)) / 2.0, 0, 1};
    point3D p11 = {(1.0 + sqrt(5.0)) / 2.0, 0 -1};
    point3D p12 = {(1.0 + sqrt(5.0)) / 2.0, 0, 1};

    add_vertex(creator, p1);
    add_vertex(creator, p2);
    add_vertex(creator, p3);
    add_vertex(creator, p4);
    add_vertex(creator, p5);
    add_vertex(creator, p6);
    add_vertex(creator, p7);
    add_vertex(creator, p8);
    add_vertex(creator, p9);
    add_vertex(creator, p10);
    add_vertex(creator, p11);
    add_vertex(creator, p12);

    triangles faces[] =
    {
        {0, 11, 5},
        {0, 5, 1},
        {0, 1, 7},
        {0, 7, 10},
        {0, 10, 11},
        {1, 5, 9},
        {5, 11, 4},
        {11, 10, 2},
        {10, 7, 6},
        {7, 1, 8},
        {3, 9, 4},
        {3, 4, 2},
        {3, 2, 6},
        {3, 6, 8},
        {3, 8, 9},
        {4, 9, 5},
        {2, 4, 11},
        {6, 2, 10},
        {8, 6, 7},
        {9, 8, 1}
    };

    for (int i = 0; i < subdivide; i++)
    {
        triangles new_faces[array_size];
        int new_faces_index = 0;
        for (int j = 0; j < 20; j++)
        {
            triangles tri = faces[j];
            int a = get_middle_point(creator, tri.v1, tri.v2);
            int b = get_middle_point(creator, tri.v2, tri.v3);
            int c = get_middle_point(creator, tri.v3, tri.v1);

            new_faces[new_faces_index++] = (triangles){tri.v1, a, c};
            new_faces[new_faces_index++] = (triangles){tri.v2, b, a};
            new_faces[new_faces_index++] = (triangles){tri.v3, c, b};
            new_faces[new_faces_index++] = (triangles){a, b, c};
        }

        for (int j = 0; j < new_faces_index; j++)
        {
            faces[j] = new_faces[j];
        }

        for (int i = 0; i < 20; i++)
        {
            triangles tri = faces[i];
            result.triangle_indices[i * 3] = tri.v1;
            result.triangle_indices[i * 3 + 1] = tri.v2;
            result.triangle_indices[i * 3 + 2] = tri.v3;
        }

    }
    return result;
}

int main(void)
{
    icosphere creator;
    creator.index = -1;
    int subdivision_level = 3;
    
    creator.geometry = create_icosphere(&creator, subdivision_level);
    
    for (int i = 0; i < creator.index; i++)
    {
        printf("Vertex %d: (%f, %f, %f)\n", i, creator.geometry.positions[i].x, creator.geometry.positions[i].y, creator.geometry.positions[i].z);
    }
    
    for (int i = 0; i < creator.index; i += 3)
    {
        printf("Triangle %d: %d, %d, %d\n", i / 3, creator.geometry.triangle_indices[i], creator.geometry.triangle_indices[i + 1], creator.geometry.triangle_indices[i + 2]);
    }
    
    int count = creator.geometry.triangle_indices;

    return 0;
}

c stack-overflow
1个回答
0
投票

您应该注意到您链接的页面上的代码中广泛使用了 C# 中的

new
关键字。它为那些正在创建的东西分配内存。您的代码中没有
new
,因为 C 没有。您需要使用
malloc()
stdlib.h
分配内存。 (后来
free()
释放资源,因为 C 没有像 C# 那样的垃圾收集器。)

positions
cache
triangle_indices
是您从未在代码中设置的指针。这些指针需要设置为
malloc()
将返回的大小适当的内存块,以覆盖您将在这些指针上使用的所有索引值。

© www.soinside.com 2019 - 2024. All rights reserved.