Where did you write:
atoms = (struct Atom *) malloc(sizeof(struct Atom) * numAtoms); atoms = (*amino).atoms;
I think your intention should be like this:
atoms = (struct Atom *)malloc(sizeof(struct Atom) * numAtoms); for (i = 0; i < numAtoms; i++) atoms[i] = (*amino).atoms[i];
which can also be written as:
atoms = (struct Atom *)malloc(sizeof(struct Atom) * numAtoms); memcpy(atoms, (*amino).atoms, sizeof(struct Atom) * numAtoms);
There is no built-in equals ( = ) operator in C for copying arrays, as you seem intended. Instead, you lose track of the pointer to the allocated memory previously stored in the atoms variable, and then proceed to the start of the first iteration of your loop with atoms , pointing to the "input copy" of the atom array.
Part of the problem is that you call
free in memory, but then you continue to access the pointer to that freed memory. You should not access pointers to freed memory. To avoid this, replace all your calls with a free one:
#ifdef free # undef free #endif #define free(f) freeptr(&f) void freeptr(void **f) { (free)(*f); *f = NULL; }
Now you can simply cut and paste the above code somewhere at the top of your program. A good place after the final #include directive, but it should happen in the file level area and before your first use of free() in your code.
After recompiling the code, you will find errors Bus errors and segmentation violations immediately after free(atom) . This is correct, and the goal of freeptr() is to cause your code to crash immediately, and not to the current situation where your code uses pointers incorrectly and leads to problems that are very difficult for you to debug.
To permanently fix memory allocation, definitely transpose the lines:
bonds = (int *) malloc(sizeof(int)); free(bonds);
which should read:
free(bonds); bonds = (int *) malloc(sizeof(int));
You use the diff argument as if you were passing an array of at least three (3) elements. You must make sure that the caller has enough memory.
When distributing
bonds you must allocate memory for one (1) integer, but as many integers as
numBonds :
free(bonds); bonds = (int *) malloc(sizeof(int) * numBonds);
or, better for most C encoders:
free(bonds); bonds = calloc(numBonds, sizeof(int));
You will need to adjust the selection of atoms to select the correct number of elements. Currently, you also allocate only one memory element of size sizeof(struct Atom) . An array of such elements requires that you multiply the size of one element by the number of elements.
The calloc() function is good because it allocates an array for you and initializes the contents of all elements to zero. malloc() does nothing to initialize the returned memory and may lead to unpredictable values ​​propagating in your program. If you use malloc() rather than calloc() , you must take care of initializing the elements of the array. Even when using calloc() you must initialize any nonzero elements.
Note that I removed the listing from the malloc return value. If you are writing C code, you must compile it as C code. The compiler will not complain about the lack of casting from void * unless you compile in C ++ mode. C source files should end with .c file extensions, not .cpp .
As Walter Mundt noted, you accidentally call free() on a member of one of your input parameters that you assigned to the atoms pointer. You will have to fix it yourself; above freeptr() will not highlight this error for you.
Others write that you cannot use printf() to reliably detect where your program crashes. The output from printf() buffered, and its appearance is delayed.
It is best to use gdb to determine the exact line with which your program crashes. You do not have to learn gdb commands to do this if you compile your code for debugging.
Without this, replace:
printf("Program ran to point A.\n");
from:
fprintf(stderr, "Program ran to point A.\nPress return.\n"); fflush(stderr); fflush(stdin); fgetc(stdin); fflush(stdin);
All in all, my suggestion is that you are not using C at the moment. Computers are so fast these days that I would question why you read C first.
Do not misunderstand me; I like the language of C. But C is not for everything. C is great for operating systems, embedded systems, high-performance computing, and for other cases where the main obstacle to success is the lack of access to low-level access to computer technology.
In your case, you seem to be a scientist or engineer. I recommend you learn and use Python. Python provides easy-to-read, easily verified programs that you can share with other chemists or engineers. C is not a fast way to write robust code like Python does. In this unlikely future event, which Python is not fast enough for your purposes, there are other solutions that you will then be ready.