I'm getting a segmentation fault in GCC compiler - arrays

The segmentation error occurs in this function:
#include <stdio.h>
#include <stdlib.h>
int heap [999],heap2 [999];
int* addDigit(int *arr, int SIZE, int D) {
int con=0;
for (int i = 0; i < SIZE; i++)
con = con * 10 + arr[i];
con += D;
int p = 0;
while (con >= 0) {
heap[p] = con % 10;
con /= 10;
p++;
}
for (int i = 0; i < p; i++)
printf("%d ", heap[i]);
heap2[0] = 11;
heap2[1] = -1;
int *pp = heap2;
return pp;
}
This is main function:
int main() {
int N, digit;
scanf("%d", &N);
int arr[N];
for (int index = 0; index < N; index++) {
scanf("%d", &arr[index]);
}
scanf("%d", &digit);
int *ptr = addDigit(arr, N, digit);
int index = 0;
while (*(ptr+index) !=-1) {
printf("%d", ptr[index]);
index++;
}
return 0;
}
Why am I getting a segmentation fault here?
This program gets input of array like [1 2 3] and value k, say 3;
it should print 1 2 6.
I used two globally declared arrays here.

Generally, the quickest way to locate the sources of segmentation faults, is the compile the program with the -g flag to include debug information in the executable, and then to run the program using Valgrind.
In this case, the segmentation fault occurs in the reading of heap here:
while (con >= 0)
{
heap[p] = con % 10;
con /= 10;
p++;
}
The variable con will eventually become 0 and will stay at 0 due to the repeated division by 10. It will not become negative, and thus the while-loop will repeat infinitely. The index p will increase until the program will try to access element 999 of heap - which is out of bounds, i.e. this is a segmentation fault.
Perhaps you meant to write while (con > 0)? This stop the loop when con is zero (instead of negative, as before). Or perhaps you need a different solution, depending on what the intended functionality of the code is exactly.
PS. The segmentation fault does not happen "in the compiler", it occurs while the program is executed.

Related

stack corruption by eliminate a printf()

some time ago I tried to program a Mergesort. In some point I got an error that I was able to solve, but still saved the code because have something strange that i don't understand. The code is the following:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef int elem;
void mergesort(elem * arr, unsigned n){
if(n != 1){
if(n == 2){
if(arr[0] > arr[1]){
int change = arr[0];
arr[0] = arr[1];
arr[1] = change;
}
}else{
unsigned i = 0, j = 0, mit = (n+1)>>2, fin = n>>2;
elem * arr_2 = (elem *)malloc(sizeof(elem) * n), * mit_arr = arr+mit;
mergesort(arr, mit);
mergesort(mit_arr, fin);
while(i < mit || j < fin){
if(arr[i] <= mit_arr[j]){
arr_2[j+i] = arr[i];
i++;
}else{
arr_2[j+i] = mit_arr[j];
j++;
}
}
for(i=0; i<n; i++)
arr[i] = arr_2[i];
free(arr_2);
}
}
}
int main(){
unsigned a = 10;
int i;
elem * arr = (elem*)malloc(sizeof(elem) * a);
arr[0] = 12;
arr[1] = 3;
arr[2] = -3;
arr[3] = 22;
arr[4] = 12;
arr[5] = 11;
arr[6] = 4;
arr[7] = 9;
arr[8] = 10;
arr[9] = 2;
printf("something\n"); // 1
mergesort(arr, a);
printf("\n");
for(i=0; i<a; i++){
printf("%d, ", arr[i]);
}
printf("\n");
free(arr);
return 0;
}
The thing is that, despite the fact that the code doesn't do what I want and it seems like there is no error, if I comment out the line marked by 1 (printf("something\\n"); ) then the error "malloc(): corrupted top size" appears. I actually don't know why something like that is possible, so I came here to see if someone have an explanation.
I tried to debug the program with gdb and got the same error, but have more information:
Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig#entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
but still without idea of what happened.
There are a couple of major issues with your code. These are things you should be able to test yourself by checking whether the values being used by your function are what you expect.
Here's the first issue. You have calculated the length of the first half of the array as (n+1)>>2, and then you assume the length of the remaining array is n>>2. That is simply not true. Shifting a value to the right by 2 binary places is a division by four.
It is far better to use "normal" math instead of attempting to be clever. This reduces the chance for errors, and makes your code easier to read.
unsigned mit = n / 2, fin = n - mit;
The other issue is your merge. You have made your while-loop run until both i and j are out-of-range. But in your loop, it's guaranteed that on at least one of the iterations, one of those values will be out-of-range.
A better way to merge arrays uses three loops. The first one runs until either of the arrays has been merged in, and the remaining two loops will copy the remaining part of the other array.
unsigned x = 0, i = 0, j = 0;
while(i < mit && j < fin){
if(arr[i] <= mit_arr[j]){
arr_2[x++] = arr[i++];
}else{
arr_2[x++] = mit_arr[j++];
}
}
while(i < mit){
arr_2[x++] = arr[i++];
}
while(j < fin){
arr_2[x++] = mit_arr[j++];
}

Deep q-learning program exited with code -1073741819

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.

Different error messages while freeing allocated memory

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.

strcpy() error: Bad permissions for mapped region at address

I have a problem with exercise 5-13 of K&R, the goal of the exercise is to make a function tail that does the same as the *nix command, here's my function:
#include <stdio.h>
#include <string.h>
#include "tail.h"
int tail(int n)
{
char *saved_lines[n];
for (int i = 0; i < n; i++)
saved_lines[i] = "\0";
int line_state[n];
for (int j = 0; j < n; j++)
line_state[j] = 0;
int num_lines = 0, i = 0;
char line[MAXLINE];
saved_lines[n - 1] = "\0";
while (get_line(line, MAXLINE) > 0)
{
for (i = 0; i < n - 1; i++)
{
strcpy(saved_lines[i], saved_lines[i + 1]);
line_state[i] = line_state[i + 1];
}
strcpy(saved_lines[n - 1], line);
line_state[n - 1] = 1;
}
printf("last %d lines: \n", n);
for (i = 0; i < n; i++)
if (line_state[i] == 1)
printf("%d: %s\n", i, saved_lines[i]);
}
problem is when I run it I get a Segmentation fault (core dumped) error, and running it through Valgrind shows the error comes from the call to strcpy:
==25284== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==25284== Bad permissions for mapped region at address 0x108E64
...I don't get why, at first strcpy had a problem with the saved_lines[i] pointers being non initialized, fixing that with
for(int i=0;i<n;i++)
saved_lines[i]="\0";
didn't help...any ideas what could cause this ? thanks in advance!
EDIT: initiated --> initialized
I believe that you've got many more problems, but one is certainly here:
int tail(int n)
{
char *saved_lines[n];
for(int i=0;i<n;i++)
saved_lines[i]="\0";
You are declaring an (variable-length) array of pointers. Then you make this pointer point to a fixed string somewhere in your data segment. Then you go and try to modify that memory. No, no.
You need to reserve memory for each of your lines. You could go for something like:
for(int i = 0; i < n; i++)
saved_lines[i] = calloc(MAXLINE, 1);
But from here there's still a lot to do. Plus you will need to free that memory later.

how do I convert an array to an long int and back to an array

You are given an integer N. Find the digits in this number that exactly divide N my code gives me a timed out message i.e. Terminated due to timeout or CPU time limit exceeded (core dumped). here is my codeenter code here
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main()
{
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int T, cnt, digits1, digits2, rem;
long long x;
char N[11];
scanf("%d", &T);
for (int i = 1; i <= T; i++)
{
scanf("%10c", N);
int x = (atoll(N));
digits1 = x;
while (digits1 != 0)
{
digits1 = x/10;
cnt++;
}
// char buffer[cnt + 1];
for(int j = 1; j <= cnt; j++)
{
rem = x % N[j];
if (rem == 0)
{
digits2++;
}
}
printf("%d", digits2);
}
return 0;
}
This looks like homework.
I'll give some pointers.
Once you have the input chars converted to an actual int or long (or long long in your case), do NOT muck around with digits - especially in base 10. If you're going to do anything like that then you may as well leave it in char array form. This bit is not needed:
while (digits1 != 0)
{
digits1 = x/10;
cnt++;
}
You have uninitialised values. Don't assume that everything is automatically initialised to zero. Sometimes you get lucky... but often you won't.
This looks good:
for(int j = 1; j <= cnt; j++)
{
rem = x % N[j]; //not quite right N is ASCII
if (rem == 0)
{
digits2++;
}
}

Resources