Below is a solution to the codewars training.
https://www.codewars.com/kata/59f4a0acbee84576800000af/train/c
Test Crashed
Caught unexpected signal: SIGSEGV (11). Invalid memory access.
I get an error message like this, what's wrong?
I think it's probably part of the strtok function, but please tell me what's wrong.
#include <stdlib.h>
#include <string.h>
double pos_average(char *s, unsigned n)
{
char **matrix;
char *p;
unsigned int i, j, k;
unsigned int subst_len = ( strchr(s,',') - s ) / sizeof(char);
double count = 0;
matrix = (char**)calloc( n + 1 ,sizeof(char*) );
if(!matrix) exit(0);
for(i = 0; i < n; i++)
{
matrix[i] = (char*)calloc( subst_len + 1 ,sizeof(char) );
if(!matrix[i]) exit(0);
}
for(i = 0; i < n; i++)
{
if(i == 0){
p = strtok(s, " ");
strncpy(matrix[i], p, subst_len);
}
else{
p = strtok(NULL," ");
strncpy(matrix[i], p, subst_len);
}
}
for(i = 0; i < n - 1; i++)
{
for(j = i + 1; j < n; j++)
{
for(k = 0; k < subst_len; k++)
{
if(matrix[i][k] == matrix[j][k]) count++;
}
}
}
for(i = 0; i < n; i++) free(matrix[i]);
free(matrix);
return (count / ( ( (double)n * ( (double)n - 1.0 ) ) / 2.0 ) ) * 100.0;
}
Related
How do I get to write to 2D pointers where I have pnumber[2%4][2%4] and how can I get pnumber with more than 3 ciphers to be displayed?
I'm making a program to write pascals triangle in C.
When the pointer pnumbers[i][j] have both i and j = 2 mod 4, except for when i and j = 2, then my program won't write to the address and give the error message:
pascals triangle: malloc.c:2406: sysmalloc: Assertion '{old_top == initial_top (av) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
Aborted.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int factorial(int p) {
if (p>=1) {
return p*factorial(p-1);
}
else {
return 1;
}
}
int NchooseM(int n, int m) {
return factorial(n)/(factorial(n-m)*factorial(m));
}
int main() {
int n =7;
int x = n-2;
int i, j, k;
/*
printf("How many rows of Pascals triangle do you want to write?\n");
scanf("%d", &n);
*/
int **pnumbers;
pnumbers = (int **) malloc(n *sizeof(int *));
/* Allocate memory for storing the individual elements in a row */
for (i = 0; i < n; i++) {
pnumbers[i] = (int *) malloc(i * sizeof(int));
}
pnumbers[0][1] = 1;
/* Calculating the value of pnumbers[k][l] */
for (i = 0; i < n; i++) {
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
/*
if (!(i % 4 == 2 && i != 2))
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
} else if (i > 2) {
for (j = 0; j <= i-1; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
}
*/
}
/* Writing out the triangle */
for (i = 0; i < n; i++) {
for (k = 0; k <= x; k++){
printf(" ");
}
for (j = 0; j <= i; j++) {
printf("%d ", pnumbers[i][j]);
}
x = x-1;
printf("\n");
}
for (i = 0; i < n; i++) {
free(pnumbers[i]);
}
free(pnumbers);
return 0;
}
When I avoid writing to these addresses and just print them out I get some seemingly random integer at these memory addresses.
Also when avoid these addresses and just print out so many rows that I get some spots with a higher integer with more than 3 siphers, it seems to overflow - and I don't see the logic behind it.
The result of running the second code
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int factorial(int p) {
if (p>=1) {
return p*factorial(p-1);
}
else {
return 1;
}
}
int NchooseM(int n, int m) {
return factorial(n)/(factorial(n-m)*factorial(m));
}
int main() {
int n =20;
int x = n-2;
int i, j, k;
/*
printf("How many rows of Pascals triangle do you want to write?\n");
scanf("%d", &n);
*/
int **pnumbers;
pnumbers = (int **) malloc(n *sizeof(int *));
/* Allocate memory for storing the individual elements in a row */
for (i = 0; i < n; i++) {
pnumbers[i] = (int *) malloc(i * sizeof(int));
}
pnumbers[0][1] = 1;
/* Calculating the value of pnumbers[k][l] */
for (i = 0; i < n; i++) {
/*
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
*/
if (!(i % 4 == 2 && i != 2))
for (j = 0; j <= i; j++) {
pnumbers[i][j] = NchooseM(i,j);
} else if (i > 2) {
for (j = 0; j <= i-1; j++) {
pnumbers[i][j] = NchooseM(i,j);
}
}
}
/* Writing out the triangle */
for (i = 0; i < n; i++) {
for (k = 0; k <= x; k++){
printf(" ");
}
for (j = 0; j <= i; j++) {
printf("%d ", pnumbers[i][j]);
}
x = x-1;
printf("\n");
}
for (i = 0; i < n; i++) {
free(pnumbers[i]);
}
free(pnumbers);
return 0;
}
But row number 13 is still quite messed up.
Code is experiencing int overflow and thus undefined behavior (UB).
With 32-bit int and int factorial(int p), p > 12 oveflows the int range.
Code could use a wider integer type (long long works up to p==20), but improvements can be made at NchooseM() to avoid overflow for higher values.
Something like the below. Works up to int n = 30;
int NchooseM(int n, int m) {
// return factorial(n)/(factorial(n-m)*factorial(m));
int nm = 1;
int den = 1;
for (int i = m+1; i <= n; i++) {
assert(INT_MAX/i >= nm);
nm *= i;
assert(nm % den == 0);
nm /= den++;
}
return nm;
}
Tried unsigned long long and works up to int n = 62;
Edit: Another bug:
I "fixed" by initializing all to 1, yet I suspect something remains amiss in /* Calculating the value of pnumbers[k][l] */ for (i = 0; i < n; i++) { code.
pnumbers[i] = malloc((i + 1) * sizeof pnumbers[i][0]);
for (int j = 0; j < i + 1; j++) {
pnumbers[i][j] = 1;
}
Aside: rather than pnumbers[i] = (int *) malloc((i+1) * sizeof(int));, consider below with no unneeded cast nor trying to match the right type.
pnumbers[i] = malloc(sizeof pnumbers[i][0] * (i+1));
Can't increase rows in 2d array, but columns is ok.
#include <stdio.h>
#include <stdlib.h>
it is working:
void increasecolumn(int ** mas, int* n, int m){
for (int i = 0; i < m; i++){
int* tmp = realloc(mas[i], sizeof (*mas[i]) * ((*n) + 1));
if (tmp){
mas[i] = tmp;
}
}
(*n) = (*n) + 1;
}
but increasing rows failed
void increaserow(int ** mas, int n, int* m){
int ** tmp = realloc(mas, sizeof(*mas) * ((*m) + 1));
if (tmp){
mas = tmp;
for (int i = 0; i < 1; i++){
mas[(*m) + i] = malloc(sizeof(*mas[(*m) + i]) * n);
}
}
(*m) = (*m) + 1;
}
int main(int argc, char * argv[]) {
int n = 3; // columns
int m = 2; // rows
int** mas = malloc(m*sizeof(*mas));
for(int i = 0; i < m; i++){
mas[i] = malloc(n*sizeof(*(mas[i])));
}
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
mas[i][j] = 0;
printf("%d ", mas[i][j]);
}
printf("\n");
}
printf("\n");
increasecolumn(mas, &n, m);
for (int i = 0; i < m; i++){
mas[i][n-1] = 1;
}
increaserow(mas, n, &m); // problem is here
for (int j = 0; j < n; j++){
mas[m-1][j] = 0;
}
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
printf("%d ", mas[i][j]);
}
printf("\n");
}
system("pause");
return 0;
}
I use this answer Resizing 2D Arrays in C like an example, something wrong.
The GNU Project Debugger on Windows:
warning: FTH: (9152): * Fault tolerant heap shim applied to current process. This is usually due to previous crashes. *
0 0 0
0 0 0
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401821 in main (argc=1, argv=0x7f1990) at D:\III Курс! II СЕМЕСТР\МатМодДослОп\stud\Untitled2.c:47
47: mas[m-1][j] = 0;
I have a problem with increasing C[] array from 6 to 10 I've faced with heap corruption problem by realloc(). I have a following code of Big M metod:
#include <stdio.h>
#include <stdlib.h>
int * mnInit(FILE * );
double * * ReadA(FILE * , int, int);
double * ReadVector(FILE * , int);
int * condtxt(FILE *, int );
void Artif_counter(int* , int *, int);
void reallocationA(double**, int* , int , int);
void increaseA(int*, double**, int, int, int);
void increaseC(double *, int);
int main(int argc, char * argv[]) {
FILE * file1 = fopen("C.txt", "r");
FILE * file4 = fopen("A.txt", "r");
FILE * file5 = fopen("Agetmn.txt", "r");
FILE * file6 = fopen("cond.txt", "r");
int * ptr_mn;
ptr_mn = mnInit(file5);
int n = * (ptr_mn);
int m = * (ptr_mn + 1);
double * * A;
A = ReadA(file4, n, m);
double * C;
C = ReadVector(file1, n);
int * cond;
cond = condtxt(file6, m);
for(int i = 0; i < m; i++){
}
//--------------------------------------------------
int BAcounter = 0;
Artif_counter(cond, &BAcounter, m);
printf("\n Basys and Artifical variable = %d", BAcounter);
reallocationA(A, &n, m, BAcounter);
increaseA(cond, A, n, m, BAcounter);
this function dont't working
increaseC(C, n);
When I trying to print arrays: the A[][] was printed right while C[] array was printed by unknown numbers and after the program Mmetod.exe was closed with problem: A heap has been corrupted (parameters: 0x00007FFCA0C1F6B0).
// count of basys and artif
//------------------------------------------------After Adding a new columns:
printf("\n A[][] ARRAY:\n");
for (int i = 0; i < m; i++) {
printf("%d ", i);
for (int j = 0; j < n; j++) {
printf(" %.3f ", A[i][j]);
}
printf("\n");
}
printf("\n\tVECTOR C[]:\n");
for (int i = 0; i < n; i++) {
printf("%lf ", C[i]);
}
fclose(file1);
fclose(file4);
fclose(file5);
fclose(file6);
free(C);
for (int i = 0; i < m; i++) {
free(A[i]);
}
free(A);
printf("\n\n");
system("pause");
return 0;
}
int * mnInit(FILE * file) {
int c;
int digit = 0;
int column = 0;
int * mnArray = malloc(2 * sizeof( * mnArray));
if (file == NULL) perror("Warning!");
else {
while (!feof(file)) {
c = fgetc(file);
if (c == ';') {
column++;
}
if (c == ' ') {
digit++;
}
}
}
* (mnArray) = (digit / column) + 1; * (mnArray + 1) = column;
return mnArray;
}
double * * ReadA(FILE * file, int n, int m) {
double * * A = malloc(m * sizeof( * A));
for (int i = 0; i < m; i++) {
A[i] = malloc(n * sizeof( * A[i]));
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
//fscanf(file ,"%lf ", &(*(*(A + i) + j)));
fscanf(file, "%lf ", & A[i][j]);
}
fscanf(file, "\n");
}
return A;
}
double * ReadVector(FILE * file, int m) { // ++++
double * Vector = malloc(m * sizeof( * Vector));
for (int i = 0; i < m; i++) {
fscanf(file, "%lf ", Vector + i);
}
return Vector;
}
int* condtxt(FILE * file, int m){
int * condA = malloc(m * sizeof(*condA));
for(int i = 0; i < m; i++){
fscanf(file, "%d", &condA[i]);
}
return condA;
}
void Artif_counter(int * cond, int *k, int m){
for(int i = 0; i < m; i++){
if(cond[i] == -1){
(*k)++;
}
if(cond[i] == 0){
(*k)++;
}
if(cond[i] == 1){
*k = (*k) + 2;
}
}
}
void reallocationA(double** A, int* n, int m, int k){
double * tmp = NULL;
for(int i = 0; i < m; i++){
tmp = realloc(A[i], ((*n) + k)*sizeof(*A[i]));
if(tmp){
A[i] = tmp;
tmp = NULL;
} else{
printf("Error! Memory isn't reallocated'");
tmp = NULL;
}
}
(*n) = (*n) + k;
}
void increaseA(int* cond, double** A, int n, int m, int k){
int presentcol = n-k;
for(int i = 0; i < m; i++){
if(cond[i] == -1){
for(int j = 0; j < m; j++){
if(j == i){
A[j][presentcol] = 1;
} else {
A[j][presentcol] = 0;
}
}
presentcol++;
}
if(cond[i] == 0){
for(int j = 0; j < m; j++){
if(j == i){
A[j][presentcol] = 1;
} else {
A[j][presentcol] = 0;
}
}
presentcol++;
}
if(cond[i] == 1){
for(int j = 0; j < m; j++){
if(j == i){
A[j][presentcol] = 1;
A[j][presentcol + 1] = -1;
} else {
A[j][presentcol] = 0;
A[j][presentcol + 1] = 0;
}
}
presentcol = presentcol + 2;
}
}
}
When I wanted to increase an array in a simple code by this function it've done and I don't understand why(
A GNU debugger rewiev: 0 warning: Critical error detected c0000374
void increaseC(double * C, int n){
double * tmp;
tmp = realloc(C, (n)*sizeof(*C)); // found out that realloc function caused an error
if(!tmp){
printf("Error");
} else{
C = tmp;
}
tmp = NULL;
}
I've made an array that is between [0,1000], and I've printed it. Next step is to arrange the array using switch statements into five different cases 0 to 199, etc. When trying to do so the for loop won't stop. I tried putting a printf after countOne in case 1, no printout occurs either.
Any suggestions
Thanks for your help
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int n;
int arraySize;
int randN;
int rand();
int countOne = 0;
int countTwo = 0;
int countThree = 0;
int countFour = 0;
int countFive = 0;
int countSix = 0;
int *p;
int *p1;
int main()
{
printf("What is the size of the array\n");
scanf("%d", &n);
//MAKING THE N-size ARRAY
int array[n];
int i;
for (i = 0; i < n; i++) {
randN = rand() % 999;
array[i] = randN;
p = (int*)malloc(i * sizeof(int));
p[i] = array[i];
}
//SORTING THE N-size ARRAY
for (i = 0; i < n; i++) {
printf("%i\n", array[i]);
}
p = (int*)malloc(sizeof(int));
p1 = (int*)malloc(5 * sizeof(int));
p1[0] = countOne;
p1[1] = countTwo;
for (i = 0; i < n; i++) {
switch (i) {
case 1:
for (i = 0; array[i] >= 0 && array[i] <= 199; i++) {
countOne++;
}
case 2:
for (i = 0; array[i] >= 200 && array[i] <= 399; i++) {
countTwo++;
return countTwo;
}
}
}
}
HERE IS MY CODE AS OF CURRENT:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int n;
int arraySize;
int randN;
int rand();
int countOne = 0;
int countTwo = 0;
int countThree = 0;
int countFour = 0;
int countFive = 0;
int countSix = 0;
int *p;
int *p1;
printf("What is the size of the array\n");
scanf("%d", &n);
//MAKING THE N-size ARRAY
int array[n];
int i;
for (i = 0 ; i < n; i++ )
{
randN=rand() % 999;
array[i]=randN;
p=(int*)malloc(i*sizeof(int));
p[i]= array[i];
}
//PRINTING THE N-size ARRAY
for (i = 0; i < n; i++)
{
printf("%i\n", array[i]);
}
//SORTING THE N-size ARRAY
int j;
for (j = 0 ; j < n ; j++)
{
switch(j)
{
case 1:
for(i = 0 ; array[i] >= 0 && array[i] <= 199; i++)
{
countOne++;
return countOne;
}
case 2:
for(i = 0 ; array[i] >= 200 && array[i] <= 399; i++)
{
countTwo++;
return countTwo;
}
}
}
HERE IS THE PRINT OUT:
What is the size of the array
3
823
7
347
There is 0 integers between 0 and 199
There is 0 integers between 200 and 399
The program has many problems.
Here is a simpler version:
#include <stdio.h>
#include <stdlib.h>
int compare_ints(const void *a, const void *b) {
const int *pa = a, *pb = b;
return (*pa > *pb) - (*pa < *pb);
}
int main(void) {
int i, n;
int stats[5] = { 0, 0, 0, 0, 0 };
printf("What is the size of the array?\n");
scanf("%d", &n);
//MAKING THE N-size ARRAY
int *array = malloc(n * sizeof(int));
int *saved = malloc(n * sizeof(int));
if (array == NULL || saved == NULL) {
printf("cannot allocate arrays\n");
exit(1);
}
for (i = 0; i < n; i++) {
int randN = rand() % 999;
saved[i] = array[i] = randN;
stats[randN / 200] += 1;
}
printf("initial array contents:\n);
for (i = 0; i < n; i++) {
printf("%i\n", array[i]);
}
printf("\n");
//SORTING THE N-size ARRAY
qsort(array, n, sizeof(*array), compare_ints);
printf("sorted array:\n);
for (i = 0; i < n; i++) {
printf("%i\n", array[i]);
}
printf("\n");
for (i = 0; i < 5; i++) {
printf("%d values between %d and %d\n", stats[i], i * 200, (i + 1) * 200 - 1);
}
printf("\n");
// do whatever else you are supposed to with array and saved
//...
free(array);
free(saved);
return 0;
}
I'm trying to implement segmented sieve of Eratosthenes in C (im beginner programmer) and it just prints proper output but I'm getting SIGSEGV when I'm submitting in on SPOJ. Can you help me spot the leak?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
void segmented_sieve(int *m, int *n, int t) {
int count, i, j, l, sqrt_imax, hlp_imin;
count = i = j = l = sqrt_imax = hlp_imin = 0;
int *imin, *imax;
imin = m;
imax = n;
sqrt_imax = (int)sqrt((double)imax[t]);
int *sieve;
sieve = malloc((imax[t] + 1) * sizeof(*sieve));
memset(sieve, 1, (imax[t] + 1) * sizeof(*sieve));
for (i = 2; i <= sqrt_imax; ++i) {
for (j = i * i; j <= imax[t]; j += i)
sieve[j] = 0;
}
int *next;
next = malloc((int)sqrt(1000000000) * sizeof(*next));
for (i = 2; i <= sqrt_imax; ++i) {
if (sieve[i] > 0) {
++count;
next[count] = i;
}
}
for (i = 1; i <= count; ++i) {
if (imin[t] <= 2) {
imin[t] = 2;
for (j = next[i]; j <= sqrt_imax; j = next[i]) {
for (l = j * j; l <= n[t]; l += j)
sieve[l] = 0;
break;
}
}
else {
hlp_imin = (int)(m[t] / next[i]);
hlp_imin *= next[i];
for (j = next[i]; j <= sqrt_imax; j = next[i]) {
for (l = hlp_imin; l <= imax[t]; l += j)
sieve[l] = 0;
break;
}
}
}
for (i = imin[t]; i < imax[t]; ++i)
sieve[i] > 0 ? printf("%d\n", i) : 0;
free(sieve);
free(next);
}
int main()
{
int t, tmp, i;
t = tmp = i = 0;
scanf("%d", &t);
int *m;
m = malloc(t * sizeof(*m));
int *n;
n = malloc(t * sizeof(*n));
for (i = 0; i < t; ++i) {
scanf("%d", &tmp);
m[i] = tmp;
scanf("%d", &tmp);
n[i] = tmp;
}
for (i = 0; i < t; ++i) {
segmented_sieve(m, n, i);
printf("\n");
}
free(m);
free(n);
return 0;
}
I fixed it by changing int to char. now just getting TLE...
Think about what happens if you get two values imin = 2,000,000,000 and imax = 2,000,000,010. You should create a tiny sieve for just 11 numbers. But you allocate storage for 2 billion ints which is probably more than your computer can handle.