I'm writing a Deep q-learning algorithm in c. I got as far as to write two functions, one that initializes the prediction network, and the other that initializes the target network by copying the weights and biases of the prediction network. I tried testing the function by printing out the weights of the initialized function, and this was the console:
hello
memory successfully allocated
(process 12600) exited with code -1073741819.
Press any key to close this window . . .
The code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define RAND_MAX 1
typedef struct neuron_t {
float activation;
float* outputWeights;
float bias;
float z;
}Neuron;
typedef struct layer_t {
int numberOfNeurons;
Neuron* neu;
}Layer;
int main() {
Layer* test = NULL;
int neus[] = { 3, 8, 8, 8, 4 };
createPredictionArchitecture(test, 5, neus);
for (int i = 0; i < 5; i++) {
for (int j = 0; i < test[i].numberOfNeurons; i++) {
for (int k = 0; k < test[i].neu[j].outputWeights[k]; i++) {
printf("\n%fl", test[i].neu[j].outputWeights[k]);
}
}
}
return 0;
}
int createPredictionArchitecture(Layer* lay, int numberOfLayers, int* neuronsInEachLayer) {
printf("hello\n");
lay = (Layer*)malloc(numberOfLayers * sizeof(Layer));
if (lay == NULL) {
printf("Failed to allocate memory in line 41\n");
exit(0);
}
else
{
printf("memory successfully allocated");
}
for (int i = 0; i < numberOfLayers; i++) {
lay[i].numberOfNeurons = neuronsInEachLayer[i];
for (int j = 0; j < lay[i].numberOfNeurons; i++) {
lay[i].neu[j].bias = 0.01; // initializes the biases
if ((i + 1) < (sizeof(neuronsInEachLayer)-1)) {
for (int k = 0; k < lay[i+1].numberOfNeurons; k++) {
double a = rand() / (double)((RAND_MAX)) * 2 - 1;
double b = sqrt((2 / (lay[i].numberOfNeurons)));
lay[i].neu[j].outputWeights[k] = a * b; // initializes the weights
}
}
}
}
free(neuronsInEachLayer);
free(&numberOfLayers);
return 0;
}
int createTargetArchitecture(Layer* predictionNetwork, Layer* targetNetwork) {
targetNetwork = (Layer*)malloc(sizeof(predictionNetwork));
*targetNetwork = *predictionNetwork;
return 0;
}
It would be great if someone could help me solve this problem.
Thanks
The exit code -1073741819 in hex is 0xC0000005. If you look up this code in Microsoft's documentation (NTSTATUS Values) you will see that it indicates that your program was terminated due to an access violation. This error can occur for a variety of reasons, including de-referencing a NULL pointer or referencing an invalid address.
You should step through your code in the debugger line by line to determine where the access violation happens. That should enable you to analyze the situation and identify the cause.
Related
I've been trying to return an array in C. I'm mostly acquainted with Java (where it's comparatively easier to return an array).
This is what I'm trying to do right now:
#include <stdio.h>
#include <stdlib.h>
int * duplicates(int[],int);
int main() {
int arr[] = {3,5,6,5,9,5,10,11,3};
int n = sizeof(arr)/sizeof(arr[0]);
int * tempArray = duplicates(arr,n);
for (int i = 0; i < n; i++) {
printf("%d \t",tempArray[i]);
}
}
int * duplicates(int arr[], int n) {
int tempArray[n];
int r = 0;
int flag = 0;
for (int i = 0; i < n; i++) {
for (int j = i+1; j < n; j++) {
if (arr[i] == arr[j]) {
for(int k = 0; k < r; k++) {
if(arr[i] == tempArray[k]) {
flag = 1;
}
}
if (flag == 0) {
tempArray[r++] = arr[i];
flag = 0;
} else {
break;
}
}
}
}
return tempArray;
}
And this, to no surprise - crashes my program. How I can return an array in C, because that feels like a bare-minimum, something I should know before I can move further into the language.
Yeah, just allocate the memory like here Returning an array using C
int * duplicates(int arr[], int n) {
int *tempArray;
...
tempArray = (int *)malloc(sizeof(int) * n);
if (tempArray == NULL)
return (NULL);
...
This will work. Google why you should 'dynamically allocate the memory' and 'pointer'.
the array you created inside function duplicate has automatic storage duration since it's on the stack of function unlike in java in which arrays are objects and allocated on the heap. anyway I just wanted to add some NOTE which is don't use VLA(variable length arrays) like int array[n] instead use literals like int array[50] since VLA generate a lot of assembly code(affect performance a tiny bit) and can have security problems like stack overflows or cause the program to crash. Also, not all compilers implement it(portability issues).
I am new to threads and I have a program that uses threads to find the minimum number out of a 2d array and later on, it finds the distance that the other elements of the array have from the minimum number and stores them in another array.
The user should enter the size of the array and the number of threads he wants to use.
I tried the program below for 1d array and it worked just fine. When I converted it to work for a 2d array it started crashing and throwing a segmentation fault. I, however, cannot find which part of the 2d declaration is wrong.
Any help is really appreciated.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#include <pthread.h>
struct Parameters
{
// input
int s,p; //n is size of array, p is number of threads
int** array; //array with elements
int start;
int end;
// output
int smallest;
int pos; //position if minimum
int** B; //array that holds the distances
};
void* min(void* args)
{
struct Parameters* p = (struct Parameters*)args;
int **array = p->array;
int **B1 = p->B;
int start = p->start;
int end = p->end;
int smallest = array[start][start];
int pos = p->pos;
int distance;
//find the smallest
for (int i = start; i < end; i++)
{
for(int j = start; j < end; j++)
{
if (array[i][j] < smallest)
{
smallest = array[i][j];
pos = i;
}
}
}
//find the distances
for(int i = 0; i < ((struct Parameters*)args) -> s; i++)
{
for(int j = 0; j < ((struct Parameters*)args) -> s; j++)
{
distance = abs(pos - i);
B1[i][j] = distance;
}
}
params->smallest = smallest;
params->B = B1;
return NULL;
}
int main()
{
int smallest,pos;
int s,p;
struct Parameters *ptr = (struct Parameters *)malloc(sizeof(struct Parameters));
if(ptr == NULL)
{
printf("Not enough. Try again \n");
exit(0);
}
printf("Type s\n");
scanf("%d",&(ptr->s));
printf("Type p\n");
scanf("%d", &(ptr->p));
// declare an array of threads and associated parameter instances
pthread_t threads[(ptr->p)];
struct Parameters thread_parameters[(ptr->p)] ;
int arr[ptr->s][ptr->s];
int B2[ptr->s][ptr->s];
// intialize the array
for(int i=0; i< ptr->s; i++)
{
for(int j=0; j< ptr->s; j++)
{
printf("Type a \n");
scanf("%d",&arr[i][j]);
}
}
// smallest needs to be set to something
smallest = arr[0][0];
// start all the threads
for (int i = 0; i < ptr->p; i++)
{
memcpy(arr, thread_parameters[i].array, sizeof(arr));
thread_parameters[i].s = ptr->s;
memcpy(Bb, thread_parameters[i].B, sizeof(B2));
thread_parameters[i].start = i * (ptr->s / ptr->p);
thread_parameters[i].end = (i+1) * (ptr->s / ptr->p);
pthread_create(&threads[i], NULL, min, &thread_parameters[i]);
}
// wait for all the threads to complete
for (int i = 0; i < ptr->p; i++)
{
pthread_join(threads[i], NULL);
}
// Now aggregate the "smallest" and "largest" results from all thread runs
for (int i = 0; i < ptr->p; i++)
{
if (thread_parameters[i].smallest < smallest)
{
smallest = thread_parameters[i].smallest;
}
}
printf("Smallest is %d\n", smallest);
thread_parameters[ptr->p].B[ptr->s][ptr->s];
for (int i = 0; i < 1; i++)
{
for(int j = 0; j < ptr->s;j++)
{
for(int k = 0; k < ptr->s; k++)
{
printf("Element %d is %d away from min\n",j,thread_parameters[i].B[j][k]);
}
}
}
return 0;
}
Thank you!!
The issue with your code might also come from :
memcpy(arr, thread_parameters[i].array, sizeof(arr));
...
memcpy(Bb, thread_parameters[i].B, sizeof(B2));
as thread_parameters[i].array and thread_parameters[i].B are not allocated, if you are only reading the array it might b fine to only pass them by address
thread_parameters[i].array = arr
but for thread_parameters[i].B you would need to allocate the arrays and perform a deep copy (memcpy would not work)
The below text does not answer the question but does provide some insight on VLA usage
One reason for causing the segmentation with a declaration of a Variable Length Array is that the value is to large to allocate the array on the stack (some compiler choose this option, this choice might have performance reason).
The is not much option to recover cleanly from failure to allocate memory on the stack as there is little way to clean up stack memory during runtime within the same stack context.
You can mitigate the issue by allocating your 2D arrays on the heap instead, some of the strategies are available here(thanks #Lundin) and here.
int** alloc_2d_int_array(size_t rows, size_t cols) {
int **result = malloc(rows * sizeof(int *));
if(result == NULL) {
// could not allocate more memory
return NULL;
}
size_t row_size = cols * sizeof(int);
for(int i=0; i < rows; ++i) {
result[i] = malloc(row_size);
if(result[i] == NULL) {
// could not allocate more memory
// cleanup
return NULL;
}
}
return result;
}
the above implementation have not been tested, but does compile, there are still risk of integer overflow.
Then use the above define function as following:
int **arr = alloc_2d_int_array(ptr->s, ptr->s);
int **B2 = alloc_2d_int_array(ptr->s, ptr->s);
easier implementation (see here(thanks #Lundin))
int **arr = malloc(sizeof(int[ptr->s][ptr->s]);
int **B2 = malloc(sizeof(int[ptr->s][ptr->s]);
I created a struct, called ArrayCount, that contains a double array and an integer that should count how often an array occurs.
If the size of the double-array is n, the idea is, to create an array of the struct ArrayCount of the size n! (n! is called m in my code).
The idea is to safe each permutation in the ArrayCount-array, counting the occurrences of each permutation, for a given algorithm. But that's just the background information and not part of the problem.
I am having issues while freeing the memory that was allocated for the double-Arrays.
Oddly enough, ~ 1/10 times my code compiles without an error message and sometimes different error messages appear.
error message:
munmap_chunk(): invalid pointer
Aborted (core dumped)
error message:
free(): invalid size
Aborted (core dumped)
error message:
Segmentation fault (core dumped)
Part of the code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
double* array_copy(const double* a, int n) {
srand(time(NULL));
double* copy = calloc(n, 8);
for(int i = 0; i < n; i++) {
copy[i] = a[i];
}
return copy;
}
void shuffle(double* a, int n) {
for(int i = n - 1; i >= 0; i--) {
time_t t;
/* Intializes random number generator */
srand((unsigned) time(&t));
double* copy = array_copy(a, i + 1);
//Generates random numbers in the closed intervall [0,i].
int random = rand() % (i + 1);
a[i] = a[random];
a[random] = copy[i];
free(copy);
}
}
// Refers to a double array and counts how often this array has
occurred yet.
typedef struct {
double* array;
int counter;
} ArrayCount;
// Computes the factorial of n: n!.
int factorial(int n) {
int result = 1;
for (int i = 2; i <= n; i++) {
result *= i;
}
return result;
}
/*
Saves all permutations in array_counts, for a given double array of
the length n and counts how often each permutations occurs.
(Hint given by our supervisor: Save a copy of a in array_counts)
*/
void update_array_counts(/*INOUT*/ ArrayCount* array_counts, int m,
/*IN*/ const double* a, int n) {
double* copy_a = array_copy(a, n);
//Increases the counter by 1, if a is already listed in
array_counts
for(int i = 1; i <= m; i++) {
int count = 0;
for(int j = 0; j < n; j++) {
if(array_counts[i].array[j] == a[j]) count++;
}
if(count == n) {
array_counts[i].counter++;
free(copy_a);
return;
}
}
//Saves a in array_counts and sets the counter to 1, if a is not
listed in array_counts, yet
for(int i = 1; i <= m; i++) {
int count = 0;
for(int j = 0; j < n; j++) {
if(array_counts[i].array[j] == 0) count++;
}
if(count == n) {
for(int j = 0; j < n; j++) {
array_counts[i].array[j] = a[j];
}
array_counts[i].counter = 1;
free(copy_a);
return;
}
}
}
// Gibt die Häufigkeit der verschiedenen Permutationen eines Arrays
der Länge n aus.
void shuffle_frequency(int n) {
double a[n];
for (int i = 0; i < n; i++) {
a[i] = i;
}
int m = factorial(n);
ArrayCount* array_counts = calloc(m, sizeof(ArrayCount));
for(int i = 1; i <= m; i++){
array_counts[i].array = calloc(n, sizeof(double));
}
for (int i = 0; i < 1000 * m; i++) {
shuffle(a, n);
update_array_counts(array_counts, m, a, n);
}
for (int i = 1; i <= m; i++) {
printf("%4d%8d ", i, array_counts[i].counter);
}
//The next free-statement is causing problems.
for(int i = 1; i <= m; i++) {
printf("i = %d\n", i);
free(array_counts[i].array);
}
free(array_counts);
}
int main(void) {
shuffle_frequency(4);
return 0;
}
What am I doing wrong?
I am having issues while freeing the memory that was allocated for the
double-Arrays. Oddly enough, ~ 1/10 times my code compiles without an
error message and sometimes different error messages appear.
complies without error message or runs without error message? I see runtime errors ( Segfault or Abort signals, to be exact ) not compile time. kl
for (int i = 1; i <= m; i++) {
The correct way to iterate through an array of m elements is
for(int i=0; i < m; i++){
As pointed out in the comments, offsets start at 0 and to to m-1, not m. That makes free(array_counts[i].array) becomes free(array_counts[m].array) What's at array_counts[m]? Could be various things, which might be deterministic or nondeterministic at runtime, but it is outside the memory you allocated. Behavior of free is undefined in this case, as it is whenever passed an address that wasn't allocated with malloc and friends.
Consider http://man7.org/linux/man-pages/man3/malloc.3.html, a copy of the manpage for free:
The free() function frees the memory space pointed to by ptr, which
must have been returned by a previous call to malloc(), calloc(), or
realloc(). Otherwise, or if free(ptr) has already been called
before, undefined behavior occurs.
I am trying to randomly fill a 2d array with values then multiply them, but for some odd reason when I run my code, on the last iteration, I get a segmentation fault. I have tried decreasing the number I am passing it and everything, but the fault still persists. Here is the code I am trying to execute, any help is much appreciated, thanks.
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *matrixFile;
int n = atoi(argv[1]); // the number of matrices
int i, j; // must declare outside of for loop due to resolve C99 mode error
double arrA[n][n];// = CreateRandomMatrix(n);
double arrB[n][n];
double sumArr[n][n];
matrixFile = fopen("home/acolwell/Documents/CPE631_HW2_Number1/results.txt", "w+");
printf("Usage: %s <size of nxn matrices>\n", argv[1]);
// randomly populate arrA and arrB
for(i = 0; i < n; i++)
{
printf("%d\n", i);
for(j = 0; j < n; j++)
{
printf("%4d", j);
arrA[i][j] = (double)rand()/(double)RAND_MAX;
arrB[i][j] = (double)rand()/(double)RAND_MAX;
}
}
printf("Exiting Matrix randomization");
// multiply the matrices and write them to the file
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
sumArr[i][j] = arrA[i][j] * arrB[i][j];
printf("Writing matrix ");
fprintf(matrixFile, "%0.3lf\n", sumArr[i][j]);
}
}
if(matrixFile)
{
fclose(matrixFile);
}
matrixFile = NULL;
return 0;
}
This error is going to come down to writing off the end of your array or failure to open your file. I would suggest running gdb to check out your program when it is running, but from a quick glance I wonder if you don't mean to have
"/home/acolwell/Documents/CPE631_HW2_Number1/results.txt"
as the file to write instead of
"home/acolwell/Documents/CPE631_HW2_Number1/results.txt"
I would suggest checking the result of your fopen call before calling fprintf.
If n is large enough, you'll generate a stack overflow using VLAs. I've verified this experimentally with your code (e.g. use n of 5000).
So, you'll need to use malloc to allocate from heap. But, that would require a bit of a rewrite.
Here's a way to use heap allocation and get the benefit of a VLA [using some slight trickery]:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define C(_arr) (double (*)[(size_t)(n)]) _arr
void
docalc(FILE *fout,int n,double arrA[n][n],double arrB[n][n],double sumArr[n][n])
{
// must declare outside of for loop due to resolve C99 mode error
int i,
j;
// randomly populate arrA and arrB
for (i = 0; i < n; i++) {
printf("%d\n", i);
for (j = 0; j < n; j++) {
printf("%4d", j);
arrA[i][j] = (double) rand() / (double) RAND_MAX;
arrB[i][j] = (double) rand() / (double) RAND_MAX;
}
}
printf("Exiting Matrix randomization");
// multiply the matrices and write them to the file
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
sumArr[i][j] = arrA[i][j] * arrB[i][j];
printf("Writing matrix\n");
fprintf(fout, "%0.3lf\n", sumArr[i][j]);
}
}
}
int
main(int argc, char *argv[])
{
FILE *matrixFile;
int n = atoi(argv[1]); // the number of matrices
printf("Usage: %s <size of nxn matrices>\n", argv[1]);
matrixFile = fopen("/tmp/results.txt", "w+");
if (matrixFile == NULL) {
perror("fopen");
exit(1);
}
double *arrA = malloc(sizeof(double) * n * n);
double *arrB = malloc(sizeof(double) * n * n);
double *sumArr = malloc(sizeof(double) * n * n);
docalc(matrixFile,n,C(arrA),C(arrB),C(sumArr));
if (matrixFile)
fclose(matrixFile);
matrixFile = NULL;
return 0;
}
I just compiled and tested your code. The file name you are giving is incorrect; you need a "/" in front of "home".
Not sure what the requirements are, but write your matrixFile like a matrix: add a new line after each row of the matrix is "multiplied", not after every element:
for(i = 0; i < n; i++) {
for(j = 0; j < n; j++) {
sumArr[i][j] = arrA[i][j] * arrB[i][j];
printf("Writing matrix ");
fprintf(matrixFile, "%0.3lf ", sumArr[i][j]);
}
fprintf(matrixFile, "\n");
}
Also, take Craig Easley's comment seriously. Stack Overflow can happen, even off the premises this website ;) Consider allocating your matrix dynamically on the heap.
I'm looking to create a program that creates and stores N random complex numbers. However, it's necessary to use another array (of pointers) which points to every element on the complex array. Then, I have to present it sorted by its norm to the user.
To "sort" it, I just change to where the pointer array is pointing to. Then I just show the "sorted" array of pointers.
But I'm not getting it right. How can I achieve this?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#define FORMATLOG "FORMATLOG: invalid parameters: ex3 <N>"
#define RANGE 18 - 6
enum { true, false };
typedef struct {
double real,
imag,
norm;
} Complex;
void generateComplex(int N) {
int i, test;
Complex vector[N];
for(i = 0; i < N; i++) {
vector[i].real = rand() % RANGE;
do { vector[i].imag = rand() % RANGE; } while(vector[i].imag == 0);
vector[i].norm = sqrt(pow(vector[i].real, 2) + pow(vector[i].imag, 2));
}
Complex *p_vect = &vector;
/* makes array point in order */
while(test == false) {
test == true;
for(i = 0; i < N - 1; i++)
if(vector[i].norm > vector[i + 1].norm) {
*p_vect[i] = &vector[i + 1];
*p_vect[i + 1] = &vector[i];
test = false;
}
}
for(i = 0; i < N; i++)
printf("\t%d -| %2g + %2gi | = %g\n", i, vector[i].real,
vector[i].imag,
vector[i].norm);
printf("********************************\n");
for(i = 0; i < N; i++)
printf("\t%d -| %2g + %2gi | = %g\n", i, p_vect[i].real,
p_vect[i].imag,
p_vect[i].norm);
}
int main(int argc, char **argv) {
if(argc != 2) {
puts(FORMATLOG);
return false;
}
srand(time(NULL));
int i, N = atoi(argv[1]);
generateComplex(N);
return true;
}
Complex *p_vect = &vector;
This creates a pointer to the existing array. The requirement is to create an array of pointers, not a pointer to an array.
Complex *p_vect[N];
for (i = 0; i < N; i++) {
p_vect[i] = &vector[i];
}
If you start with this, you can then sort p_vect without touching vector. Your sorting code, when written correctly, will make no mention of vector at all.