UPDATE: The problem with the segmentation fault is not within this function as described below, it is within another function of the same program.
I'm trying to make a program that animates bouncing balls, however I am quite stuck and can't figure out what I am doing wrong. I believe I have isolated the problem to be within the function below. I have sort of figured out that it has something to do with the new-model statements.
Anyway, upon running the code I get segmentation fault and the values drawn by the function (in terms of triangles) are way out of where they should be. I should be getting values between 0 and 1600 but I end up with 94 million sometimes.
Any help is greatly appreciated!
object_t *create_object(SDL_Surface *surface, triangle_t *model, int numtriangles){
object_t *new=malloc(sizeof(object_t));
new->surface = surface;
new->model = malloc(sizeof(triangle_t)*numtriangles);
*new->model= *model;
new->numtriangles = numtriangles;
new->tx = surface->w/2;
new->ty = surface->h/2;
new->scale = 0.1;
new->rotation = 0.0;
return new;
}
NB! The triangle_t *model pointer points to an array which describes multiple triangles.
EDIT:
Including struct of object:
typedef struct object object_t;
struct object {
float scale; /* Object scale */
float rotation; /* Object rotation */
float tx, ty; /* Position on screen */
float speedx, speedy; /* Object speed in x and y direction */
unsigned int ttl; /* Time till object should be removed from screen */
int numtriangles; /* Number of triangles in model */
triangle_t *model; /* Model triangle array */
SDL_Surface *surface; /* SDL screen */
};
And struct of triangles:
typedef struct triangle triangle_t;
struct triangle {
/* Model coordinates, where each pair resemble a corner */
int x1, y1;
int x2, y2;
int x3, y3;
/* The color the triangle is to be filled with */
unsigned int fillcolor;
/* Scale factor, meaning 0.5 should half the size, 1 keep, and 2.0 double */
float scale;
/* The point (tx, ty) where the center of the teapot should be placed on-screen */
int tx, ty;
/* The degrees the triangle is supposed to be rotated at the current frame */
float rotation;
/*
* Bounding box of on-screen coordinates:
* rect.x - x-coordinate of the bounding box' top left corner
* rect.y - y-coordinate of the bounding box' top left corner
* rect.w - width of the bounding box
* rect.h - height of the bounding box
*/
SDL_Rect rect;
/* On-screen coordinates, where each pair resemble a corner */
int sx1, sy1;
int sx2, sy2;
int sx3, sy3;
};
This line is copying only the first triangle:
*new->model = *model;
From the point of view of your function model is only a pointer to an object. The compiler doesn't know it points to an array of triangles, hence we need to pass the number of triangles in there as an argument.
Replace it for:
memcpy( new->model, model, sizeof(triangle_t)*numtriangles);
Additional comments:
Remember to free the model when freeing the object
Replace new for something else like newObj if you ever consider to compile this with a c++ compiler
More info:
https://linux.die.net/man/3/memcpy
https://en.cppreference.com/w/c/string/byte/memcpy
[EDIT]
Regarding to the segmentation fault: your function is correct now and it is not causing SEGFAULT unless you are running out of memory, what is very unlikely. Anyway, if you are running out of memory and getting a SEGFAULT in that function then the problem is either:
you are not deallocating memory correctly somewhere else and then you have a memory leak making you run out of memory improperly.
your platform needs more memory what, despite unlikely, is possible especially if it is a limited embedded platform
Post another question with the backtrace of the segfault.
Related
I am currently writing a C program with a struct called Rectangle. The code below shows how I set it up.
typedef struct {
int width;
int height;
int x;
int y;
} Rectangle;
After that, I made another struct called Ellipse which contained exactly the same values as the Rectangle struct, as well as some more.
I wanted to keep my code neat so I decided to make a base struct called Shape.
I used this Shape struct in the header of my other structs.
typedef struct {
int width;
int height;
int x;
int y;
} Shape;
typedef struct {
Shape shape;
} Rectangle;
typedef struct {
Shape shape;
int angle;
int anchor_x;
int anchor_y;
} Ellipse;
Now whenever I make an instance of one of these structs, VSCode thinks there's an error.
Rectangle *rect;
rect -> width = 100;
VSCode puts an error squiggle under width that says struct "<unnamed>" has no field "width", but when I compile the code, it works perfectly.
Why does VSCode raise this error? Should I be doing things differently? How can I stop it from making unnecessary squiggles?
Please be patient, I am new to C programming.
You don't have a field width inside Rectangle - you have a field shape. Presumably what you wanted to do is rect->shape.width = 100.
Notice that your code won't work as-is because you never allocate memory for rect.
I am writing a program and the part I am working on at the moment must take hundreds of triangles (that form a 3D shape) and store the coordinates of each triangle. For example, one triangle will have coordinates: (x1, y1, z1) (x2, y2, z2) (x3, y3, z3).
I think perhaps organising a struct in this way would be a start (but I am open to better ideas..!)
struct triangle {
double x1;
double y1;
double z1;
double x2;
double y2;
double z2;
double x3;
double y3;
double z3;
};
Essentially, I wish to be able to store each triangle's coordinates and then at another point in the program I would like to go back and delete some triangles and add some others to the 'list'.
I've been trying to do this for days now and any help would be much appreciated - it's driving me crazy...
Thanks in advance! Let me know if I can explain anything in better detail.
First, you might want to use a more user-friendly structures as:
struct coord_s {
double x;
double y;
double z;
}
struct triangle_s {
struct coord_s points[3];
}
Then, as far as malloc is concerned, you can allocate a pointer to a struct using malloc as such struct triangle_s *my_triangle = malloc(sizeof(struct triangle_s));
sizeof() will take care of calculating the size of the actual structure and send it to malloc()
Then you just need to choose what to use as storage depending on your use case
So, I'm pretty new to the C language and I've been passed a project by my professor to make a game in C. My problem is, I created a structure like so:
typedef struct vector
{
int parts;
int dir;
} Vector;
typedef struct snake
{
Vector* parts;
Vector dir;
} Snake;
I'm trying to initialize the parts pointer within this function:
void init_snake(struct snake *snake, int size, int x, int y)
{
snake->parts = (Vector *)malloc(sizeof(Vector) * size);
for (int i = 0; i < size; i++)
{
//sets the body parts one after the other in a line
snake->parts[i].x = x - i * PIXEL_SIZE;
snake->parts[i].y = y;
}
//sets the snake direction to the left
snake->dir.x = 1;
snake->dir.y = 0;
}
But by doing that the array parts inside the snake pointer is not initialized as expected. By checking its size with sizeof(snake.parts) / sizeof(Vector) it returns 0. Any ideas of how to fix it?
It likely is working, you're just confused about sizeof. This operator measures the size (in bytes) of a type. If you ask for the size of a value, it uses the type of that expression instead.
This is a compile-time evaluation and therefore is not dynamic.
sizeof(snake.parts) is the same as sizeof(Vector*) which will be either 4 or 8 bytes depending on whether you are compiling to a 32-bit or 64-bit target. Therefore, it's not useful to determine the size of an allocation.
Generally, given a pointer, you cannot tell how large the allocation is. Usually this is handled by storing some kind of useful length somewhere else. For example, you could modify struct snake to include an element count for parts:
typedef struct snake
{
Vector* parts;
int parts_size;
Vector dir;
} Snake;
And set this value accordingly:
snake->parts = (Vector *)malloc(sizeof(Vector) * size);
snake->parts_size = size;
I'm trying to make a struct that contains another struct with multiple arrays. I need to dynamically allocate those arrays too, so I think I need another pointer still.
int arraysize;
typedef struct Array{
int *size = arraysize;
unsigned int val[*size];
unsigned int x[*size];
unsigned int y[*size];
} Array;
typedef struct Image{
int height;
int width;
int max;
Array *data;
} Image;
OK, so once I finally figure that out, I still need to figure out how to dynamically allocate that memory using malloc. I'm totally lost there too. Any help at all would be greatly appreciated.
EDIT: more clarification:
I'm using the arrays to store three pieces of information that are all connected. Think of a chessboard, you could say knight E4, which tells you that on the 4th column of row E, there is a knight. If you started this process at A1 and ended at K10 you'd have a full chessboard right? The image struct is analogous to the chessboard, the Array is analogous to a list of a bunch of squares that compose the chessboard and the contents of those squares. (E.g. A1 null A2 knight a3 bishop etc...) Unfortunately, I don't know what kind of board will be passed through, it might be a 3x7 board or a 9x2 board etc. So I need to dynamically allocate the memory for those possibilities. Once I have the memory allocated I need to store information about the location and the contents of all of the "squares." Then I need to let a program pass through the height of the board, width of the board and the list of contents and I'd be done the hard part.
What you actually meant was:
typedef struct data {
unsigned int x;
unsigned int y;
unsigned int val;
} Data;
typedef struct image {
int height;
int width;
int max;
Data* data;
} Image;
and somewhere:
Image i;
i.height = 10;
i.width = 20;
i.data = malloc(sizeof(Data) * i.width * i.height);
...
// one of the ways how to access Data at 2nd row, 3rd column:
*(i.data + i.width * 1 + 2).val = 7;
...
free(i.data);
i.data = NULL;
But what you actually need is some good book ;)
I have been trying to modify the code beneath to work with NEON Intrinsics, thereby creating a speedup. Unfortunately nothing seems to work correctly. Does anyone have any idea what is going wrong? I updated the doubles to single floating point elements.
typedef float REAL;
typedef REAL VEC3[3];
typedef struct driehoek
{
VEC3 norm; /* Face normal. */
REAL d; /* Plane equation D. */
VEC3 *vptr; /* Global vertex list pointer. */
VEC3 *nptr; /* Global normal list pointer. */
INT vindex[3]; /* Index of vertices. */
INT indx; /* Normal component max flag. */
BOOL norminterp; /* Do normal interpolation? */
BOOL vorder; /* Vertex order orientation. */
}driehoek;
typedef struct element
{
INT index;
struct object *parent; /* Ptr back to parent object. */
CHAR *data; /* Pointer to data info. */
BBOX bv; /* Element bounding volume. */
}ELEMENT;
INT TriangleIntersection(RAY *pr, ELEMENT *pe, IRECORD *hit)
{
FLOAT Rd_dot_Pn; /* Polygon normal dot ray direction. */
FLOAT Ro_dot_Pn; /* Polygon normal dot ray origin. */
FLOAT q1, q2;
FLOAT tval; /* Intersection t distance value. */
VEC3 *v1, *v2, *v3; /* Vertex list pointers. */
VEC3 e1, e2, e3; /* Edge vectors. */
driehoek *pt; /* Ptr to triangle data. */
pt = (driehoek *)pe->data;
Rd_dot_Pn = VecDot(pt->norm, pr->D);
if (ABS(Rd_dot_Pn) < RAYEPS) /* Ray is parallel. */
return (0);
hit->b3 = e1[0] * (q2 - (*v1)[1]) - e1[1] * (q1 - (*v1)[0]);
if (!INSIDE(hit->b3, pt->norm[2]))
return (0);
break;
}
return (1);
}
An array of float vec[3] is not enough of a hint to the compiler that NEON intrinsic can be used. The issue is that float vec[3] has each element individually addressable. The compiler must store each in a floating point register. See gcc NEON intrinsic documentation.
Although 3 dimensions is very common in this Universe, our friends the computers like binary. So you have two data types that can be used for NEON intrinsics; float32x4_t and float32x2_t. You need to use the intrinsics such as vfmaq_f32, vsubq_f32, etc. These intrinsics are different for each compiler; I guess you are using gcc. You should only use the intrinsic data types as combining float32x2_t with a single float can result in movement between register types, which is expensive. If your algorithm can treat each dimension separately, then you might be able to combine types. However, I don't think you will have register pressure and the SIMD speed-up should be beneficial. I would keep everything in float32x4_t to begin with. You maybe able to use the extra dimension for 3D-projection when it comes to the rendering phase.
Here is the source to a cmath library called math-neon under LGPL. Instead of using intrinsics with gcc, it uses inline assembler.Neon intrinsics vs assembly
See also: armcc NEON intrinsics, if you are using the ARM compiler.