Dynamic Array C - c

I am trying to solve the Dynamic Array problem of Hackerrank in C. I tried so many ways but all in vain. The best I could do is to clear 4 test cases. I am getting a segmentation error. Please help me find where am I doing wrong. It will be really helpful.
Question Link: https://www.hackerrank.com/challenges/dynamic-array/problem
We are supposed to complete the function. So here is my attempt:
int *dynamicArray(int n, int queries_rows, int queries_columns, int **queries,
int *result_count) {
*result_count = 0;
int *result = (int *)malloc(queries_rows * sizeof(int));
int i = 0, j = 0, y, x;
int lastAnswer = 0;
int **arr = (int **)malloc(n * sizeof(int *));
int *size = (int *)malloc(n * sizeof(int));
for (i = 0; i < n; i++) {
size[i] = 0;
}
for (i = 0; i < n; i++) {
arr[i] = (int *)malloc(n * sizeof(int));
}
for (i = 0; i < queries_rows; i++) {
x = queries[i][1];
y = queries[i][2];
if (queries[i][0] == 1) {
size[(x ^ lastAnswer) % n]++;
arr[(x ^ lastAnswer) % n][size[(x ^ lastAnswer) % n] - 1] = y;
} else {
lastAnswer = arr[(x ^ lastAnswer) % n][y % size[(x ^ lastAnswer) % n]];
printf("%d\n", lastAnswer);
(*result_count)++;
result[(*result_count) - 1] = lastAnswer;
}
}
result = (int *)realloc(result, (*result_count) * sizeof(int));
return result;
}

Your implementation is a little too complicated: you should use an intermediary variable idx as specified in the problem statement:
Create a 2-dimensional array arr, of n empty arrays. All arrays are zero indexed.
Create an integer lastAnswer, and initialize it to 0.
There are types of queries:
Query: 1 x y
Find the list within arr at index idx = (x ^ lastAnswer) % n.
Append the integer y to the arr[idx].
Query: 2 x y
Find the list within arr at index idx = (x ^ lastAnswer) % n.
Find the value of element y % size(arr[idx]) where size is the number of elements in arr[idx], Assign the value to lastAnswer.
Print the new value of lastAnswer on a new line.
Assuming the function prototype is correct, here is a simpler version:
int *dynamicArray(int n, int queries_rows, int queries_columns, int **queries,
int *result_count) {
int **arr = (int **)malloc(n * sizeof(int *));
int *size = (int *)calloc(n * sizeof(int));
int *result = (int *)malloc(queries_rows * sizeof(int));
int i, j;
int count = 0;
int lastAnswer = 0;
for (i = 0; i < n; i++) {
arr[i] = (int *)malloc(n * sizeof(int));
}
for (i = 0; i < queries_rows; i++) {
int x = queries[i][1];
int y = queries[i][2];
int idx = (x ^ lastAnswer) % n;
if (queries[i][0] == 1) {
arr[idx][size[idx]++] = y;
} else {
lastAnswer = arr[idx][y % size[idx]];
printf("%d\n", lastAnswer);
result[count++] = lastAnswer;
}
}
*result_count = count;
for (i = 0; i < n; i++) {
free(arr[i]);
}
free(arr);
free(size);
return (int *)realloc(result, count * sizeof(int));
}
The problem with this implementation is the size of the lists in the array arr may grow larger than n. You should therefore reallocate them as you append values.
Here is a modified version:
int *append_list(int **list, int size, int value) {
*list = realloc(*list, (size + 1) * sizeof(int));
(*list)[size] = value;
return p;
}
int *dynamicArray(int n, int queries_rows, int queries_columns, int **queries,
int *result_count) {
int **arr = (int **)malloc(n * sizeof(int *));
int *size = (int *)calloc(n * sizeof(int)); // initializes to 0
int *result = NULL;
int i, j;
int count = 0;
int lastAnswer = 0;
for (i = 0; i < n; i++) {
arr[i] = NULL;
}
for (i = 0; i < queries_rows; i++) {
int x = queries[i][1];
int y = queries[i][2];
int idx = (x ^ lastAnswer) % n;
if (queries[i][0] == 1) {
append_list(&arr[idx], size[idx]++, y);
} else {
lastAnswer = arr[idx][y % size[idx]];
printf("%d\n", lastAnswer);
append_list(&result, count++, lastAnswer);
}
}
for (i = 0; i < n; i++) {
free(arr[i]);
}
free(arr);
free(size);
*result_count = count;
return result;
}

Related

lottery generation function using 'void'

i need to use 'void lotto_gen(void)' function but i don't know how to make this => lotto[i + (j * 5)] = lotto_gen(); right. output should look like this picture enter image description here
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void lotto_gen()
{
int ball = 1 + rand() % 45;
}
void swap(int* a, int* b)
{
int r;
r = *a;
*a = *b;
*b = r;
}
void shuffle(int* arr, int size)
{
int i, r;
for (i = 0; i < size; i++)
{
r = rand() % (size - i) + i;
swap(arr + i, arr + r);
}
}
int main(void)
{
int i, j;
int lotto[50] = { 0 };
int size = sizeof(lotto) / sizeof(lotto[0]);
srand(time(0));
for (j = 0; j < 10; j++)
{
for (i = 0; i < 5; i++)
lotto[i + (j * 5)] = lotto_gen();
}
for (j = 0; j < 10; j++)
{
printf("[");
for (i = 0; i < 5; i++)
printf("%d ", lotto[i + (j * 5)]);
printf("]\n");
}
return 0;
}
From your comment, "It states that the problem does not require parameters in lotto_gen()" -- If this is only the problem constraint, then you have your freedom to choose the return type. Why not go with int lotto_gen(void) instead of void lotto_gen(void). You can have your lotto_gen() function like this:
/* ..... */
int lotto_gen(void)
{
return (1 + rand() % 45);
}
/* .... */

What's wrong with the function multiplyTwoMatrices() in this C code for finding fibonacci using matrix multiplication?

#include<stdio.h>
void multiplyTwoMatrices(int (*)[2], int[][2], int[][2]);
void copyMatrix(int[][2], int[][2]);
void powerAMatrix(int[][2], int[][2], int);
int main()
{
int num;
scanf("%d", &num);
int i;
for(i = -1; i <= num; i++)
{
printf("\n%d", fib(i));
}
}
int fib(int num)
{
if(num <= 0)
{
return 0;
}
else
{
int matrix[2][2] = {{1, 1}, {1, 0}};
//int fibMatrix[2][2] = powerAMatrix(matrix[2][2], num);
int fibMatrix[2][2];
powerAMatrix(fibMatrix, matrix, num);
return getFibNum(fibMatrix);
}
}
void powerAMatrix(int fibMatrix[2][2], int matrix[2][2], int num)
{
//fibMatrix = matrix;
copyMatrix(fibMatrix, matrix);
int i = 0;
for(i = 1; i < num; i++)
{
//fibMatrix = fibMatrix * matrix;
multiplyTwoMatrices(fibMatrix, fibMatrix, matrix);
}
}
void copyMatrix(int destinationMatrix[2][2], int sourceMatrix[2][2])
{
int i = 0; int j = 0;
for(i = 0; i < 2; i++)
for(j = 0; j < 2; j++)
destinationMatrix[i][j] = sourceMatrix[i][j];
}
void multiplyTwoMatrices(int multipliedMatrix[2][2], int matrixA[2][2], int matrixB[2][2])
{
int i = 0; int j = 0; int k = 0;
for(i = 0; i < 2; i++)
{
for(j = 0; j < 2; j++)
{
multipliedMatrix[i][j] = 0; //or just initialize it as a zero matrix.
for(k = 0; k < 2; k++)
{
multipliedMatrix[i][j] += (matrixA[i][k] * matrixB[k][j]);
}
}
}
//working alternative
/*
int x = matrixA[0][0]*matrixB[0][0] + matrixA[0][1]*matrixB[1][0];
int y = matrixA[0][0]*matrixB[0][1] + matrixA[0][1]*matrixB[1][1];
int z = matrixA[1][0]*matrixB[0][0] + matrixA[1][1]*matrixB[1][0];
int w = matrixA[1][0]*matrixB[0][1] + matrixA[1][1]*matrixB[1][1];
multipliedMatrix[0][0] = x;
multipliedMatrix[0][1] = y;
multipliedMatrix[1][0] = z;
multipliedMatrix[1][1] = w;
*/
}
int getFibNum(int fibMatrix[2][2])
{
return fibMatrix[0][1];
}
The function multiplyTwoMatrices() seems to work only if "working alternative" (code closed in comments inside this function) is used instead of the one used currently. I'm unable to understand what is going wrong with this code. A little help is appreciated.
Output expected: 0 0 1 1 2 3 5 8 ...
Output coming: 0 0 1 1 1 1 1 1 ...
while your multiplication function is correct, it doesn't work correctly when the destination is one of the operands; if it is, the operand is changed there while the calculation is underway.
Either require that multipliedMatrix is distinct from both matrixA and matrixB (that'd be preferred), or have a temporary matrix there and copy it into the result!
P.S. it would be much easier wrapping the matrix class into a struct:
struct intmatrix2x2 {
int values[2][2];
};
this would make implicit copies when calling functions; and instead of copyMatrix you can say:
struct intmatrix2x2 b = a;
and your multiplication could read as
struct intmatrix2x2 multiply(struct intmatrix2x2 a, struct intmatrix2x2 b)
{
struct intmatrix2x2 result;
int i = 0; int j = 0; int k = 0;
for(i = 0; i < 2; i++)
{
for(j = 0; j < 2; j++)
{
result.values[i][j] = 0; //or just initialize it as a zero matrix.
for(k = 0; k < 2; k++)
{
result.values[i][j] += a.values[i][k] * b.values[k][j]);
}
}
}
return result;
}
and you could use it as
struct intmatrix2x2 result = multiply(a, b);

free() crashes the code

#include <stdio.h>
#include <stdlib.h>
void printingArr(int** arr, int rows);
void sortingEachOneOfThem(int** pArr, int rows);
void sortingTheWholeArray(int** pArr, int rows);
void bubbleSort(int* arr);
void freeArray(int **a, int m);
int main(void)
{
int** pArr = 0;
int numOfRows = 0;
int sizes = 0;
printf("Enter number of rows: ");
scanf("%d", &numOfRows);
pArr = (int**) malloc(sizeof(int*) * numOfRows);
if (pArr == NULL)
{
printf("Unsuccessful malloc!\n");
return 1;
}
for (int i = 0; i < numOfRows; i++)
{
printf("Enter array length for row %d: ",i);
scanf("%d", &sizes);
pArr[i] = (int*) malloc(sizeof(int) * sizes + 1);
if (pArr[i] == NULL)
{
printf("Unsuccessful malloc!\n");
return 1;
}
pArr[i][0] = sizes;
for (int k = 1; k < sizes + 1; k++)
{
printf("Enter value for array: ");
scanf("%d", &pArr[i][k]);
}
}
printingArr(pArr, numOfRows);
sortingEachOneOfThem(pArr, numOfRows);
printingArr(pArr, numOfRows);
sortingTheWholeArray(pArr, numOfRows);
printingArr(pArr, numOfRows);
for (int i = 0; i < numOfRows; i++)
{
if (pArr[i] != NULL)
{
free(*(pArr + i));
}
}
//free(pArr);
system("pause");
return 0;
}
/*
this amazing, wonderfull piece of program prints the array given
input: int** arr, int rows
output: none
*/
void printingArr(int** arr, int rows)
{
int i = 0;
int k = 0;
for (i = 0; i < rows; i++)
{
for (k = 0; k <= arr[i][0]; k++)
{
printf("%d ", arr[i][k]);
}
printf("\n");
}
printf("\n");
}
/*
This beautiful function sorts the whole array, but its length of rows like a pyramid
input: int** arr, int rows
output: none
*/
void sortingTheWholeArray(int** pArr, int rows)
{
int* temp = 0;
int i = 0, k = 0;
for (i = 0; i < rows - 1; i++)
{
for (k = 0; k < rows - 1; k++)
{
if (pArr[k][0] > pArr[k + 1][0])
{
temp = pArr[k];
pArr[k] = pArr[k + 1];
pArr[k + 1] = temp;
}
}
}
}
/*
This little small function sorts every row of the array of arrays given to it
input: int** arr, int rows
output: none
*/
void sortingEachOneOfThem(int** pArr, int rows)
{
int i = 0;
for (i = 0; i < rows; i++)
{
bubbleSort(pArr[i]);
}
}
/*
This little piece of a code is a bubble sort, sorts the array given to it :)
input: int* arr, int rows
output: none
*/
void bubbleSort(int* arr)
{
int i = 1, k = 0;
for (i = 1; i < arr[0] - 1; i++)
{
for (k = 1; k <= arr[0] - i; k++)
{
if (arr[k] > arr[k + 1])
{
arr[k] += arr[k + 1];
arr[k + 1] = arr[k] - arr[k + 1];
arr[k] -= arr[k + 1];
}
}
}
}
the free at the end crashes my code, showing this error:
https://i.stack.imgur.com/nqxBG.png
the same usage of the function free() on another code worked good, but not here. I have tried running through it in step by step mode, it crashes at the first free. Dr. memory shows this: https://i.stack.imgur.com/rSZJr.png
another link: https:// i.stack. imgur.com/ZX2Ne.png (paste it without the spaces in the middle, Can't post more than 2 links)
what can I do?
This:
pArr[i] = (int*) malloc(sizeof(int) * sizes + 1);
under-allocates. Adding a single byte to the size of an array of int makes little sense. You probably meant:
pArr[i] = malloc((sizes + 1) * sizeof *pArri[i]);
Don't cast the return value of malloc(), and use sizeof on the left-hand side.

Heap Corruption on resize array by realloc() function in C

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;
}

Fault in Multiple Realloc C Pointers

my program fails always in the 4th realloc and I don't understand why it makes the 3 first good and then it fails. I'm using triple pointer and I've tried to debugate and all works good until the 4th realloc when it says that its out of scope and segmention fault.
#include <stdio.h>
#include <stdlib.h>
void rellenar(int ***movimiento, int mov, int discos) {
int j, pos, mov2, ***movimiento2;
mov2 = mov + 1;
movimiento = realloc(movimiento, mov2 * sizeof (int **));
movimiento[mov] = malloc(3 * sizeof (int *)); //3 de torres
for (j = 0; j < 3; ++j) {
movimiento[mov][j] = malloc(discos);
}
printf("%d\n", mov);
for (pos = 0; pos < discos; pos++) {
movimiento[mov][0][pos] = 1;
movimiento[mov][1][pos] = 1;
movimiento[mov][2][pos] = 1;
printf("%d", movimiento[mov-1][0][pos]);
printf("%d", movimiento[mov-1][1][pos]);
printf("%d\n", movimiento[mov-1][2][pos]);
}
}
int main(int argc, char** argv) {
int ***movimiento, i, j, movs = 1, discos = 4, pos, mov;
movimiento = malloc(movs * sizeof (int **));
for (i = 0; i < movs; ++i) {
movimiento[i] = malloc(3 * sizeof (int *)); //3 de torres
for (j = 0; j < 3; ++j) //3 de torres
{
movimiento[i][j] = malloc(discos);
}
}
for (pos = 0; pos < discos; pos++) {
movimiento[0][0][pos] = discos - pos;
movimiento[0][1][pos] = 0;
movimiento[0][2][pos] = 2;
}
for (pos = 0; pos < discos; pos++) {
printf("%d", movimiento[0][0][pos]);
printf("%d", movimiento[0][1][pos]);
printf("%d\n", movimiento[0][2][pos]);
}
for (mov = 1; mov < 6; mov++) {
rellenar(movimiento, mov, discos);
}
}
What's wrong?
Rather than triple-nested mallocs and reallocs, which are inefficient and hard to keep straight, just do your allocation in a single shot:
size_t total = mov2 * 3 * discos;
int* movimiento = malloc(total * sizeof(int));
Now you can fill it like this:
for (size_t ii = 0; ii < total; ++ii)
movimiento[ii] = 1;
Then make an indexing function:
int* get_cell(int* matrix, size_t x, size_t y, size_t z, size_t max_y, size_t max_z) {
return &matrix[x*max_y*max_z + y*max_z + z];
}
So then:
int two = *get_cell(movimiento, mov, 1, pos, 3, discos);
And when it's time to release the memory, it's simply:
free(movimiento);

Resources