realloc() is screwing up my data... what's going on? - c

I'm writing a variable list implementation. In my insertion step, I check if the array's size is maxed out, and if so I double the maximum capacity and call realloc() to allocate me some new memory. Going from size 2 to 4, 4 to 8, and 8 to 16 works fine, but going from size 16 to 32 gives me some random zeroes in my array. Can anyone tell me what's going on here? I know I could avoid using realloc() by mallocing some new space, using memcpy and then freeing the old pointer... and perhaps there's no performance hit from doing that. But my intuition tells me that there is, and in any case I thought that's what realloc was there for. Can anyone tell me what's going on? The key function in this code is the append function.
#include <stdio.h>
#include <stdlib.h>
#include "problem5.h"
#define FAILURE -1
#define SUCCESS 0
ArrayList ArrayList_Init(int n, int (*append) (ArrayList, int), void (*print) (ArrayList), void (*insert) (ArrayList, int, int), void (*destroy) (ArrayList), int (*valueOf) (ArrayList, int))
{
ArrayList newArrayList = (ArrayList) malloc(sizeof(ArrayList_));
newArrayList->max_size = n;
newArrayList->current_size = 0;
newArrayList->data = malloc(n*sizeof(int));
newArrayList->append = append;
newArrayList->destroy = destroy;
newArrayList->print = print;
newArrayList->insert = insert;
newArrayList->valueOf = valueOf;
return newArrayList;
}// init a new list with capacity n
int append_(ArrayList list, int val)
{
//if the array is at maximum capacity
//double the capacity
//update max_size
//insert the value in the first open spot in the array (aka index current_size)
//increment current_size
if (list->current_size == list->max_size) {
list->max_size *= 2;
if (( list->data = realloc(list->data, list->max_size) ) == NULL)
return FAILURE;
}
list->data[list->current_size] = val;
list->current_size++;
return SUCCESS;
}
void print_(ArrayList list)
{
int i;
printf("List of size %d, max size %d. Contents:\n", list->current_size, list->max_size);
for (i=0; i<list->current_size; i++)
printf("%d, ", list->data[i]);
printf("\n");
}
void insert_(ArrayList list, int val, int index) {
}// insert val into index
void destroy_(ArrayList list)
{
//free list memory
}
int valueOf_(ArrayList list, int index)
{
//return value of specified element
return 0;
}
int main()
{
ArrayList list;
int stat, count = 0;
list = ArrayList_Init(2, append_, print_, insert_, destroy_, valueOf_); // init a new list with capacity 8
do {
printf("Appending %d\n", count);
stat = list->append(list, count) ; // add val to end of the list
list->print(list);
} while (stat == SUCCESS && ++count < 20);
return 0;
}
And here's the output of this:
Appending 0
List of size 1, max size 2. Contents:
0,
Appending 1
List of size 2, max size 2. Contents:
0, 1,
Appending 2
List of size 3, max size 4. Contents:
0, 1, 2,
Appending 3
List of size 4, max size 4. Contents:
0, 1, 2, 3,
Appending 4
List of size 5, max size 8. Contents:
0, 1, 2, 3, 4,
Appending 5
List of size 6, max size 8. Contents:
0, 1, 2, 3, 4, 5,
Appending 6
List of size 7, max size 8. Contents:
0, 1, 2, 3, 4, 5, 6,
Appending 7
List of size 8, max size 8. Contents:
0, 1, 2, 3, 4, 5, 6, 7,
Appending 8
List of size 9, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8,
Appending 9
List of size 10, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
Appending 10
List of size 11, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
Appending 11
List of size 12, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
Appending 12
List of size 13, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
Appending 13
List of size 14, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
Appending 14
List of size 15, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
Appending 15
List of size 16, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
Appending 16
List of size 17, max size 32. Contents:
0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,
Appending 17
List of size 18, max size 32. Contents:
0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 17,
Appending 18
List of size 19, max size 32. Contents:
0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 17, 18,
Appending 19
List of size 20, max size 32. Contents:
0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 17, 18, 19,

It is very bad to write so:
list->data = realloc(list->data, list->max_size)
You should use new variable and if memory was reallocated you write so:
List->data = temp;
It will protect you from memory leak.
And you forgot *sizeof(int)

Related

How to get used elements from space complexity optimized 0-1 knapsack

I have implemented 0-1 knapsack. "DP" is the 1D table that holds maximum profits. "capacity" is the maximum capacity, "n" is the number of elements. At the end it holds the last row of 2D classic approach in "DP". But i can't figure out how to get which elements are used with just looking at the 1D array.
DP = (int*)calloc(capacity + 1, sizeof(int));
used = (int*)calloc(n, sizeof(int));
for (i = 0; i < n; i++) {
for (j = capacity; j > 0; j--) {
if (weight[i] <= j && DP[j] < DP[j - weight[i]] + profit[i]) {
DP[j] = DP[j - weight[i]] + profit[i];
used[i] = 1;
}
}
}
// for example
// int profit[] = { 7, 16, 13, 8, 1, 11, 14, 11, 12, 7, 6, 10, 1, 1, 11, 12}
// int weight[] = { 6, 2, 7, 2, 1, 2, 5, 4, 12, 16, 1, 4, 10, 12, 12, 2}
// results DP = {0, 6, 16, 22, 28, 34, 39, 45, 47}
// total profit of used elements: 72 <- it should be 47
// total weight of used elements: 20 <- it should be lesser than 8(the capacity)

size of two dimension array

int main()
{
int a[3][4] = {
{0, 1, 2, 3} , // initializers for 0 row
{4, 5, 6, 7} , // initializers for 1 row
{8, 9, 10, 11} // initializers for 2 row
};
int b[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
printf("size of *a = %ld\n", sizeof(*a));
printf("size of *b = %ld\n", sizeof(*b));
//these prints out 16.
//why is this 16?
Hello, I am learning c in school and I have a question.
why is the size of a(and b) 16?? How does it work?

Initialize elements of GSL matrix

I have allocated a large gsl_matrix and would like to allocate all its elements with known float values. Is there a way to do it without using gsl_matrix_set for each element? I am looking for the equivalent of fortran's reshape function to initialize a matrix.
A = reshape( (/0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7/), (/ 8, 8/) )
Matrices only support limited setting of all values, that is by gsl_matrix_set_all, gsl_matrix_set_zero or gsl_matrix_set_identity.
However, you can create and initialise an array and then create a matrix view from that using gsl_matrix_view_array, gsl_matrix_const_view_array, gsl_matrix_view_array_with_tda or gsl_matrix_const_view_array_with_tda. (Matrix views are common in GSL. For example, they are used to express sub-matrices returned by gsl_matrix_submatrix.) The matrix view is a struct which contains a field matrix upon which you execute the gsl_matrix methods you wish to apply.
For example, compile with gcc matrixview.c -lgsl -lgslcblas the following file matrixview.c:
#include <stdio.h>
#include <gsl/gsl_matrix.h>
#define rows 2
#define cols 3
int main () {
const double data[rows*cols] = {
0.0, 0.1, 0.2,
1.0, 1.1, 1.2,
};
const gsl_matrix_const_view mat = gsl_matrix_const_view_array( data, rows, cols );
for ( size_t row = 0; row < rows; ++row ) {
for ( size_t col = 0; col < cols; ++col ) {
printf( "\t%3.1f", gsl_matrix_get( &mat.matrix, row, col ) );
}
printf( "\n" );
}
}

fwrite() puts unknown zero

I have one strange problem while using fwrite() in C.After editing of file with integers, i get zero ("0") before my last element which added by fwrite().My exercise is to divide integers in file on groups which are consisted of 10 elements or less.
For example, i have :
{2, 3, 9, 4, 6, 7, 5, 87, 65,12, 45, 2, 3, 4, 5, 6, 7, 8, 9}
after editing i need :
{2, 3, 9, 4, 6, 7, 5, 87, 65, 12, 87, 45, 2, 3, 4, 5, 6, 7, 8, 9, 45 };
With code below I get:
{2, 3, 9, 4, 6, 7, 5, 87, 65, 12, 87, 45, 2, 3, 4, 5, 6, 7, 8, 9, 0, 45 };
In the process of step-by-step debugging fwrite() works only two times, it wites 87 after first ten elements, and 45 after remained.Zero wasn`t writed by fwrite().Is that so?From where it comes finally?
My code:
while (!feof(fp)) {
fread(&elems[k], sizeof(int), 1, fp);
fwrite(&elems[k], sizeof(int), 1, hp);
++k;
if (k == 10 || feof(fp)){
for (i = 0; i < 10; ++i){
if (elems[i] > max_number){
max_number = elems[i];
}
}
fwrite(&max_number, sizeof(int), 1, hp);
for (i = 0; i < 10; ++i){
elems[i] = 0;
}
max_number = INT_MIN;
k = 0;
}
}
Thank for answers!
Using feof will result in reading an extra item.
Must check for errors from fwrite and fread calls.
One possible error is the EOF error.
If fread returns 0 items read the value will be left at whatever it was before. Probably 0. Which is probably where your extra 0 comes from.

Removing row and column of matrix after looking for a value (C)

I made a question some hours ago but I get myself in a mess on what I had to do after finishing what I was asking on that question. All the solutions that the people gave me were ok, but useless for what I was really looking for as I didn't wrote the question as it has to be. I've to save an important position of a value, and it wasn't necessary to be saved on the other question to solve the problem. So here's the proper one.
(everything's is explained with an example above, understanding it is easy) I've a 8x8 matrix, and after choosing the row I desire, I want to get the three minimum elements of it, and choose one of this three randomly. Then, remove the row and column that contains this number. The thing is that I'dont know how to handle those three elements and remove the columns/rows. I just know how to get the minimum element, that is the following code.
int pieza[ROWS][COLS] = {
0, 2, 2, 5, 3, 2, 1, 1,
0, 4, 5, 2, 4, 3, 0, 0,
0, 4, 2, 2, 1, 2, 3, 2,
0, 3, 1, 5, 1, 2, 3, 4,
2, 5, 6, 5, 3, 1, 2, 7,
8, 2, 0, 0, 0, 2, 1, 1,
1, 2, 2, 1, 1, 6, 3, 4,
0, 1, 3, 2, 0, 0, 0, 0,
};
int myrow = 3; // the row I want to analyze
int index;
int min=0;
for (index=0;index<8;index++) {
printf("%d", piezas[myrow][index] );
if(piezas[myrow][index]<min)
min=piezas[myrow][index];
printf("\t\t");
}
printf("min: %d", min);
This is what I want to do. If the initial matrix is (which is always a nxn matrix):
{
0, 2, 2, 5, 3, 2, 1, 1,
0, 4, 5, 2, 4, 3, 0, 0,
0, 4, 2, 2, 1, 2, 3, 2,
0, 3, 1, 5, 1, 2, 3, 4,
2, 5, 6, 5, 3, 1, 2, 7,
8, 2, 0, 0, 0, 2, 1, 1,
1, 2, 2, 1, 1, 6, 3, 4,
0, 1, 3, 2, 0, 0, 0, 0,
};
And I choose row number 3:
0, 3, 1, 5, 1, 2, 3, 4,
The algorithm must choose the three minimum elements of that row.
0, 1, 1
And choose randomly one of these three. If, for example, it choose the first 'one'...
0, **1**, 1
... the algorithm must go to the 3th column of that line (becaue that was the position that was that '1') and remove the row and column, so the output matrix will be as follows, one dimension less than the original matrix (beucase you have removed a row and a column):
{
0, 2, 5, 3, 2, 1, 1,
0, 4, 2, 4, 3, 0, 0,
0, 4, 2, 1, 2, 3, 2,
2, 5, 5, 3, 1, 2, 7,
8, 2, 0, 0, 2, 1, 1,
1, 2, 1, 1, 6, 3, 4,
0, 1, 2, 0, 0, 0, 0,
};
I only know how to arrive to the line, but I'm having problems to handle three minimums because I'm having tons of problems pointers and I'm not a lot into C. Thanks in advance
Example to be sorted with the number of column.
#include <stdio.h>
#include <stdlib.h>
typedef struct pair {
int value, column;
} Pair;
int cmp(const void *a, const void *b){
Pair *pa = (Pair *)a;
Pair *pb = (Pair *)b;
return pa->value - pb->value;
}
int main(void){
int data[8] = {0, 3, 1, 5, 1, 2, 3, 4};
Pair data_pair[8];
int i;
for(i=0;i<8;++i){
data_pair[i].value = data[i];
data_pair[i].column = i;
}
qsort(data_pair, 8, sizeof(Pair), cmp);
for(i=0;i<3;++i)
printf("value = %d, column = %d\n", data_pair[i].value, data_pair[i].column);
return 0;
}
/* result
value = 0, column = 0
value = 1, column = 2
value = 1, column = 4
*/
#include <stdio.h>
#include <string.h>
#define SIZE 8
void delrow(int a[SIZE][SIZE], int row){
if(row < SIZE - 1)
memmove(&a[row], &a[row+1], (SIZE*SIZE - SIZE*(row+1))*sizeof(int));
};
void delcol(int a[SIZE][SIZE], int col){
int r;
if(col < SIZE - 1){
for(r=0;r<SIZE;++r){
memmove(&a[r][col], &a[r][col+1], (SIZE - (col+1))*sizeof(int));
}
}
}
int main(void){
int piezas[8][8] = {
0, 2, 2, 5, 3, 2, 1, 1,
0, 4, 5, 2, 4, 3, 0, 0,
0, 4, 2, 2, 1, 2, 3, 2,
0, 3, 1, 5, 1, 2, 3, 4,
2, 5, 6, 5, 3, 1, 2, 7,
8, 2, 0, 0, 0, 2, 1, 1,
1, 2, 2, 1, 1, 6, 3, 4,
0, 1, 3, 2, 0, 0, 0, 0,
};
//test
int row = 8, col = 8;
int r,c;
delrow(piezas, 3);
row -= 1;
for(r=0;r<row;++r){
for(c=0;c<col;++c)
printf("%2d", piezas[r][c]);
printf("\n");
}
printf("\n");
delcol(piezas, 1);
col -= 1;
for(r=0;r<row;++r){
for(c=0;c<col;++c)
printf("%2d", piezas[r][c]);
printf("\n");
}
return 0;
}
/* result
0 2 2 5 3 2 1 1
0 4 5 2 4 3 0 0
0 4 2 2 1 2 3 2
2 5 6 5 3 1 2 7
8 2 0 0 0 2 1 1
1 2 2 1 1 6 3 4
0 1 3 2 0 0 0 0
0 2 5 3 2 1 1
0 5 2 4 3 0 0
0 2 2 1 2 3 2
2 6 5 3 1 2 7
8 0 0 0 2 1 1
1 2 1 1 6 3 4
0 3 2 0 0 0 0
*/
Below is extract to get a nth smallest element from a selected row -Your first requirement before removing a row and column.
Copy the row
Sort the copied row (save index too while sorting)
Sorted index represents position of value in sorted order
pick 0 th or 1st or nth min indexing the sorted index.
------------ Very Draft code ---- try optimize -------
#include <stdio.h>
#include<memory.h>
void sortIndex(int *array, int *arrayIdx)
{
int i=0,j=0;
int temp=0;
int tempArr[4];
memcpy(tempArr, array, 4*sizeof(int));
for(i=0;i<4;i++)
{
printf("%d ",tempArr[i]);
}
printf("\n");
for(i=0;i<4;i++)
{
for(j=i+1;j<4;j++)
{
if(tempArr[i]>tempArr[j])
{
temp = arrayIdx[i];
arrayIdx[i]=arrayIdx[j];
arrayIdx[j]=temp;
temp = tempArr[i];
tempArr[i]=tempArr[j];
tempArr[j]=temp;
}
}
}
printf("Sorted array Index\n");
for(i=0;i<4;i++)
{
printf("%d ",arrayIdx[i]);
}
printf("\n");
printf("Sorted array Value\n");
for(i=0;i<4;i++)
{
printf("%d ",array[arrayIdx[i]]);
}
printf("\n");
}
int main ()
{
int array[4][4] = {{4,3,2,1},{7,5,4,3},{6,5,4,4},{5,5,2,1}};
int sortedIdx[4] = {0,1,2,3};
int i,ii;
for(i=0;i<4;i++)
{
for(ii=0;ii<4;ii++)
printf("%d ",array[i][ii]);
printf("\n");
}
printf("(Note:Count from 0). Which Row : ");
scanf("%d",&i);
sortIndex(array[i],sortedIdx);
printf("\n");
printf("(Nth smallest value)Give a N value (0 to 3): ");
scanf("%d",&ii);
printf(" (%d) smallest value in row (%d) is (%d)\n",ii,i,array[i][sortedIdx[ii]]);
printf("Now call function to remove Row (%d) and column (%d)\n",i,sortedIdx[ii]);
return 0;
}

Resources