jacobsax jacobsax - 10 days ago 7
C Question

Sporadic C errors apear

I'm new to programming in C and am mainly playing around with it (I normally work in Java) so please excuse my ignorance if this is an obvious error... I've just started making a simple text based Space Sim and I get two different strange errors that will sporadically appear every 2-3 runs that I'm struggling to decipher (only 1 appears at a time). I'm assuming that I have allocated a variable incorrectly, but I could do with some help having it pointed out.

The code is split into 3 files:

Physics.c:

typedef enum { false, true } bool; //define what a boolean is

//define a vector
typedef struct {
int x;
int y;
} Vector;

bool compareVectors(Vector vectorA, Vector vectorB){
if ((vectorA.x == vectorB.x) && (vectorA.y == vectorB.y)){
return true;
} else {
return false;
}
}


Space.c:

#include <stdio.h>
#include <stdlib.h>
#include "Physics.c" //includes space

enum Type {
craft = 0,
planet,
star
};


typedef struct {
enum Type type;
Vector position;
} Object;

typedef struct {
Object *array;
int used;
int size;

} Space;


void initSpace(Space *a, int initialSize) {
a->array = (Object *)malloc(initialSize * sizeof(int));
a->used = 0;
a->size = initialSize;
}

//inserts a new object in space and returns the location of the new object in the array
int insertToSpace(Space *a, Object element) {
if (a->used == a->size) {
a->size *= 2;
a->array = (Object *)realloc(a->array, a->size * sizeof(int));
}
a->array[a->used++] = element;

return a->used - 1;
}

void freeSpaceArray(Space *a) {
free(a->array);
a->array = NULL;
a->used = a->size = 0;
}

//creates a new object in space and returns the location of the object in the array
int createObjectInSpace(Space *a, int type, int xPos, int yPos){
Object newObject;
Vector tempVector;

newObject.type = type;
tempVector.x = xPos;
tempVector.y = yPos;
newObject.position = tempVector;

return insertToSpace(a, newObject);
}

//returns the number of objects at that location in space based on Vector location
int objectsAtLocationVector(Space *a, Vector pos){
int count = 0;
for (int i = 0; i < a->used; i++){
if (compareVectors(a->array[i].position, pos)){
count++;
}
}
return count;
}

//returns the number of objects at that location in space, based on an x/y int location
int objectsAtLocationInt(Space *a, int xPos, int yPos){
Vector tempVector;
tempVector.x = xPos;
tempVector.y = yPos;
return objectsAtLocationVector(a, tempVector);
}

//returns a list of all objects at the specified location vector
Space getObjectsAtLocationVector(Space *space, Vector pos){
Space newSpace;
int noOfObjects = objectsAtLocationVector(space, pos);

initSpace(&newSpace, noOfObjects);

if (noOfObjects > 0){
for (int i = 0; i < space->used; i++){
if (compareVectors(space->array[i].position, pos)){
insertToSpace(&newSpace, space->array[i]);
}
}
}

return newSpace;
}
//returns a list of all objects at the specified integer location
Space getObjectsAtLocationInt(Space *space, int xPos, int yPos){
Vector tempVector;
tempVector.x = xPos;
tempVector.y = yPos;
return getObjectsAtLocationVector(space, tempVector);
}


Main (Space_In_C.c):

#include <stdio.h>
#include "Space.c" //includes space

//Setup the main variables
void setup(Vector *myShip, Space *space){
myShip -> x = 0;
myShip -> y = 0;

initSpace(space, 10); //initialise the space array

return;
}

int main(int argc, char *argv[]) {
Vector myShip; //create the Vector that stores the ships location
Space space; //create the Space array

setup(&myShip, &space); //set up all key variables

createObjectInSpace(&space, planet, 7, 5);
createObjectInSpace(&space, craft, 7, 5);

Space objects = getObjectsAtLocationInt(&space, 7, 5);

printf("%d", objects.array[1].type);

return 0;
}


And here is the first error:

Terminated due to signal: SEGMENTATION FAULT (11)
0 lli 0x000000010705dda9 void std::__1::seed_seq::generate<unsigned int*>(unsigned int*, unsigned int*) + 9993
1 lli 0x000000010705e83b void std::__1::seed_seq::generate<unsigned int*>(unsigned int*, unsigned int*) + 12699
2 libsystem_platform.dylib 0x00007fffbd52fbba _sigtramp + 26
3 libsystem_platform.dylib 0x00007fff59489ce0 _sigtramp + 2616566080
4 lli 0x0000000106f303fe llvm::raw_ostream& llvm::operator<<<llvm::BasicBlock>(llvm::raw_ostream&, llvm::DomTreeNodeBase<llvm::BasicBlock> const*) + 12270
5 lli 0x0000000106fe21f6 llvm::SmallVectorImpl<std::__1::pair<unsigned int, llvm::TypedTrackingMDRef<llvm::MDNode> > >::operator=(llvm::SmallVectorImpl<std::__1::pair<unsigned int, llvm::TypedTrackingMDRef<llvm::MDNode> > >&&) + 4038
6 lli 0x0000000106d2376f std::__1::__tree<std::__1::__value_type<llvm::StringRef, llvm::StringRef>, std::__1::__map_value_compare<llvm::StringRef, std::__1::__value_type<llvm::StringRef, llvm::StringRef>, std::__1::less<llvm::StringRef>, true>, std::__1::allocator<std::__1::__value_type<llvm::StringRef, llvm::StringRef> > >::destroy(std::__1::__tree_node<std::__1::__value_type<llvm::StringRef, llvm::StringRef>, void*>*) + 23615
7 lli 0x0000000106d20b4e std::__1::__tree<std::__1::__value_type<llvm::StringRef, llvm::StringRef>, std::__1::__map_value_compare<llvm::StringRef, std::__1::__value_type<llvm::StringRef, llvm::StringRef>, std::__1::less<llvm::StringRef>, true>, std::__1::allocator<std::__1::__value_type<llvm::StringRef, llvm::StringRef> > >::destroy(std::__1::__tree_node<std::__1::__value_type<llvm::StringRef, llvm::StringRef>, void*>*) + 12318
8 lli 0x0000000106d20c9e std::__1::__tree<std::__1::__value_type<llvm::StringRef, llvm::StringRef>, std::__1::__map_value_compare<llvm::StringRef, std::__1::__value_type<llvm::StringRef, llvm::StringRef>, std::__1::less<llvm::StringRef>, true>, std::__1::allocator<std::__1::__value_type<llvm::StringRef, llvm::StringRef> > >::destroy(std::__1::__tree_node<std::__1::__value_type<llvm::StringRef, llvm::StringRef>, void*>*) + 12654
9 lli 0x0000000106788426 void std::__1::vector<unsigned long long, std::__1::allocator<unsigned long long> >::__push_back_slow_path<unsigned long long>(unsigned long long&&) + 24694
10 libsystem_c.dylib 0x00007fffbd3b717f __cxa_finalize_ranges + 339
11 libsystem_c.dylib 0x00007fffbd3b74b2 exit + 55
12 lli 0x0000000106d22d56 std::__1::__tree<std::__1::__value_type<llvm::StringRef, llvm::StringRef>, std::__1::__map_value_compare<llvm::StringRef, std::__1::__value_type<llvm::StringRef, llvm::StringRef>, std::__1::less<llvm::StringRef>, true>, std::__1::allocator<std::__1::__value_type<llvm::StringRef, llvm::StringRef> > >::destroy(std::__1::__tree_node<std::__1::__value_type<llvm::StringRef, llvm::StringRef>, void*>*) + 21030
13 lli 0x0000000106788290 void std::__1::vector<unsigned long long, std::__1::allocator<unsigned long long> >::__push_back_slow_path<unsigned long long>(unsigned long long&&) + 24288
14 libdyld.dylib 0x00007fffbd322255 start + 1
15 libdyld.dylib 0x0000000000000002 start + 1120787886
Stack dump:
0. Program arguments: lli /var/folders/9k/f9_xm4857vq6_fysth4wl5mh0000gn/T/com.coderunnerapp.CodeRunner/CodeRunner/clang/Space_In_C.ll


And the second error:

Terminated due to signal: ABORT TRAP (6)
lli(5537,0x7fffc60423c0) malloc: *** error for object 0x7ff8e8603fc0: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
00 lli 0x0000000107f84da9 void std::__1::seed_seq::generate<unsigned int*>(unsigned int*, unsigned int*) + 9993
1 lli 0x0000000107f8583b void std::__1::seed_seq::generate<unsigned int*>(unsigned int*, unsigned int*) + 12699
2 libsystem_platform.dylib 0x00007fffbd52fbba _sigtramp + 26
3 libsystem_platform.dylib 0x00000001109c10d0 _sigtramp + 1397298480
4 libsystem_c.dylib 0x00007fffbd3b6420 abort + 129
5 libsystem_malloc.dylib 0x00007fffbd4b0fb1 szone_error + 626
6 libsystem_malloc.dylib 0x00007fffbd4a6fbf tiny_free_list_remove_ptr + 292
7 libsystem_malloc.dylib 0x00007fffbd4bb932 tiny_free_no_lock + 1484
8 libsystem_malloc.dylib 0x00007fffbd4bc0f3 free_tiny + 671
9 lli 0x0000000107c4ca82 void std::__1::vector<llvm::JITEventListener*, std::__1::allocator<llvm::JITEventListener*> >::__push_back_slow_path<llvm::JITEventListener* const&>(llvm::JITEventListener* const&&&) + 7122
10 lli 0x00000001076af1c5 void std::__1::vector<unsigned long long, std::__1::allocator<unsigned long long> >::__push_back_slow_path<unsigned long long>(unsigned long long&&) + 24085
11 libdyld.dylib 0x00007fffbd322255 start + 1
12 libdyld.dylib 0x0000000000000002 start + 1120787886
Stack dump:
0. Program arguments: lli /var/folders/9k/f9_xm4857vq6_fysth4wl5mh0000gn/T/com.coderunnerapp.CodeRunner/CodeRunner/clang/Space_In_C.ll


Apologies for the massive code dump! Any help would be much appreciated!

Answer

In initSpace, it looks like you are wanting to allocate memory for an array of Objects (which contain an enum and a Vector), but you are only allocating enough memory for an array of int's

  a->array = (Object *)malloc(initialSize * sizeof(int));

should be

  a->array = (Object *)malloc(initialSize * sizeof(Object));

There may well be other bugs, but that one stood out.