Pass values using function - arrays

this code is supposed to be a person walking to right in a 4x4 array filled with '*'. for example: if the person walks to the right R ,row zero and walks one step it would look like this:
O * * *
* * * *
* * * *
* * * *
or row one, walks two steps
* * * *
* O * *
* * * *
* * * *
row three, walks four steps
* * * *
* * * *
* * * *
* * * O
this is the original code:
#include <stdio.h>
int main ()
{
int i,k, c, f;
char z;
char a[4][4] = { {'*','*','*','*'}, {'*','*','*','*'}, {'*','*','*','*'}, {'*','*','*','*'}};
printf("Walking to the right\n");
z=getchar();
// modified array goes here []
if(z=='R')
{
printf("Row\n");
scanf("%d",&c);
printf("Steps");
scanf("%d",&f);
a[c][f]='O';
for ( i = 0; i < 4; i++ ) {
for ( k = 0; k < 4; k++ ) {
printf("%c ", a[i][k] );
}
printf("\n");
}
}
return ;
}
I would like to have the values for R, row and steps be passed using a function to int main where only the array above is printed.
I tried doing something but I don't really know where to go from here. :/
#include <stdio.h>
void print(char);
int main ()
{
char a[4][4] = { {'*','*','*','*'}, {'*','*','*','*'}, {'*','*','*','*'}, {'*','*','*','*'}};
printf("From the right\n");
z=getchar();
// modified array goes here []
void print(char z){
int i,k;
int c, f;
if(z=='R')
{
printf("Row\n");
scanf("%d",&c);
printf("Steps");
scanf("%d",&f);
a[c][f]='O';
for ( i = 0; i < 4; i++ ) {
for ( k = 0; k < 4; k++ ) {
printf("%c ", a[i][k] );
}
printf("\n");
}
}
return ;
}
#include <stdio.h>
int main ()
{
int i,k,x,c,f;
char z;
char a[4][4] = { {'*','*','*','*'}, {'*','*','*','*'},{'*','*','*','*'}, {'*','*','*','*'}};
printf("From the right\n");
z=getchar();
printf("Row\n");
scanf("%d",&c);
if(z=='R')
{
printf("Steps");
scanf("%d",&f);
a[c][f]='G';
for ( i = 0; i < 4; i++ ) {
for ( k = 0; k < 4; k++ ) {
printf("%c ", a[i][k] );
}
printf("\n");
}
}
return 0;
}
I'll appreciate any suggestions. Thanks.

Unclear however look at this:
void getCommand(char &z) {
printf("Walking to the right\n");
z = getchar();
}
void getRowAndSteps(char z, int &c, int &f) {
if (z == 'R')
{
printf("Row\n");
scanf("%d", &c);
printf("Steps");
scanf("%d", &f);
}//else...
}
void print(char a[][4]) {
for (size_t i = 0; i < 4; i++) {
for (size_t k = 0; k < 4; k++) {
printf("%c ", a[i][k]);
}
printf("\n");
}
}
int main()
{
int c, f;
char z;
char a[4][4] = { { '*','*','*','*' },{ '*','*','*','*' },{ '*','*','*','*' },{ '*','*','*','*' } };
getCommand(z);
getRowAndSteps(z, c, f);
a[c][f] = 'O';
//maybe some cycle here for each step ??
print(a);
return 0;
}
or:
int main(int argc, char * argv[])
{
if (argc != 4) {
printf("Usage: .exe side row steps");
return 0;
}
int c = atoi(argv[2]), f = atoi(argv[3]);
char z = argv[1][0];
char a[4][4] = { { '*','*','*','*' },{ '*','*','*','*' },{ '*','*','*','*' },{ '*','*','*','*' } };
a[c][f] = 'O';
//maybe some cycle here for each step ??
print(a);
return 0;
}
untested, hope it will help you

Related

I am trying to solve a special travelling salesman problem with mpi and c

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <mpi.h>
#define MaxSize 50
typedef int ElementType;
typedef int Position;
typedef int Status;
typedef struct SeqStack
{
ElementType Data[MaxSize];
Position Top;
int (*Push)(struct SeqStack *L);
int (*Pop)(struct SeqStack *L , int e);
int (*isEmpty)(struct SeqStack s);
Status (*isFull)(struct SeqStack s);
}SeqStack;
int Push(SeqStack *L)
{
if(L->Top == 0)
{
return 0;
}
printf("%d ",L->Data[--L->Top]);
return 1;
}
int Pop(SeqStack *L , int e)
{
if(L->Top==MaxSize -1)
{
return 0;
}
L->Data[L->Top++] = e;
return 1;
}
int isEmpty(SeqStack s)
{
if(s.Top != 0)
{
return 1;
}
return 0;
}
Status isFull(SeqStack s)
{
if(s.Top != MaxSize -1)
{
return 1;
}
return 0;
}
int global_max;
int ans = INT_MAX;
void *tsp(int Dis[global_max][global_max],int v[],int N,int count,int currPos,int cost,int sum,int* result,int temp[],int make_log){
temp[0]=1;
//int mode;
//printf("count:%d\n",count);
if(count == N&&Dis[currPos][1]>0){
//printf("Ans:%d,cost:%d\n",ans,cost);
if(make_log == 1){
char str[100]={'\0'};
char output[100]={'\0'};
//printf("Ans:%d,cost:%d\n",ans,cost);
FILE *log;
for(int i=0; i<N;i++){
if (i!=N-1){
sprintf(str,"%d",temp[i]);
strcat(output,str);
strcat(output,",");
}else{
sprintf(str,"%d",temp[i]);
strcat(output,str);
strcat(output,"=");
}
}
sprintf(str,"%d",cost);
strcat(output,str);
strcat(output,"\n");
log=fopen("log.txt","a");
fputs(output,log);
fclose(log);
}
if(sum> cost){
sum = cost;
ans = cost;
//printf("every ans is %d\n\n\n\n",ans);
for (int i=0;i<N;i++){
//printf("temp[%d]=%d,",i,temp[i]);
result[i]=temp[i];
//printf("result[%d]=%d,",i,result[i]);
}
}
//ans = min(ans,cost + Dis[1][currPos]);
return result;
}
for (int i = 1;i<N+1;i++){
//printf("!!!!!!! v[%d] = %d\n",i,v[i]);
if(v[i]==0&&Dis[currPos][i]>0){
//printf("cost + Dis: %d + %d\n",cost,Dis[currPos][i]);
if(cost + Dis[currPos][i] <= ans||count==N-1){
v[i] = 1;
temp[count] = i;
//printf("\ntemp[%d] = %d\n",count,temp[count]);
//printf("currPos:%d,i:%d,count:%d\n",currPos,i,count);
//printf("Ans:%d,cost:%d\n",ans,cost);
result = tsp(Dis,v,N,count + 1,i,cost + Dis[currPos][i],sum,result,temp,make_log);
//mode = 0;
v[i]= 0;
if(count==1){
for(int j = 2;j<N+1;j++){
v[j]= 0;
}
}
}else{
//printf("currPos:%d,i:%d,count:%d\n",currPos,i,count);
temp[count] = i;
for (int k = N-1;k>count;k--){
temp[k] = 0;
}
int v_copy[N];
for (int o = 1;o<N+1;o++){
v_copy[o] = v[o];
// if(currPos==3&&i==4){
// printf("v_copy[%d] = %d//",o,v_copy[o]);
// }
}
for(int j = 2;j< N + 1;j++){
if(v[j]==0){
v[j] = 1;
}
}
result = tsp(Dis,v,N,N,N,cost + Dis[currPos][i],sum,result,temp,make_log);
//printf("Fuck currpos:%d\n",currPos);
for (int o = 1;o<N+1;o++){
v[o] = v_copy[o];
// if(currPos==3&&i==2){
// printf("v[%d] = %d//",o,v[o]);
// }
}
if(count==1){
for(int j = 2;j<N+1;j++){
v[j]= 0;
}
}
}
}
}
return result;
};
void change(int n){
global_max = n;
};
int main(int argc, char const *argv[])
{
int N;
int size = 1;
int count = 1;
int log = 0;
int nthreads,my_rank;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &nthreads);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
if(argc > 2){
log = 1;
}
char x[100] = {0};
char filename[100] = {};
strcat(filename,argv[1]);
strcat(filename,".txt");
//printf("%s\n",filename);
FILE *fp=fopen(filename,"r");
if(fp==NULL){
printf("Cannot open the file,strike any key to exit!\n");
getchar();
exit(0);
}
for (int i = 0;!feof(fp);i++){
fscanf(fp,"%hhd",&x[i]);
}
N=x[0];
change(N);
int* result;
result = (int *)malloc(sizeof(int) * global_max);
int Dis[N][N], City[N];
for(int i=1;i<N;i++){
size=size*i;
}
char y[size];
for (int i=1;i<size+1;i++){
y[i] = x[i];
//printf("%d\n",y[i]);
}
for(int i=2; i < N + 1; i++){
for(int j=1; j < i ; j++){
Dis[j][i] = y[count];
Dis[i][j] = y[count];
count+=1;
//printf("(%d,%d),(%d,%d)",j,i,i,j);
//printf("%d\n",Dis[j][i]);
}
}
for(int i=0;i<N;i++){
City[i]=i + 1;//create the number of city with 1 ...... N
}
int curr_constraint = 0;
int v[N+1];
for (int i = 1; i < N+1; i++){
v[i] = 0;
}
for(int i = 1;i<N+1;i++){
curr_constraint += Dis[i][i+1];
}
v[1]= 1;
int sum = INT_MAX;
//printf("orginal ans is %d\n",ans);
//printf("Dis map:\n");
for( int i= 1;i<N+1;i++){
for(int j =1;j<N+1;j++){
if(i==j){
Dis[i][j]=0;
}
//printf("%d ",Dis[i][j]);
}
//printf("\n");
}
//printf("The orginal constraint is %d\n",curr_constraint);
int temp[N];
int* city_divided;
int cityNumber;
int current_ans;
SeqStack s;
if(nthreads > 1){
int remain = N % (nthreads - 1);
//int group_n = N /(nthreads - 1);
if(remain !=0){
if(my_rank <= remain && my_rank != 0){
cityNumber = ((N - remain)/(nthreads - 1)) + 1;
city_divided = (int*)malloc(cityNumber*sizeof(int));
for (int i = 0; i <cityNumber; i++)
{
city_divided[i] = City[(my_rank-1)*cityNumber + 1];
}
}else{
cityNumber = ((N - remain) / (nthreads - 1));
city_divided = (int*)malloc(cityNumber*sizeof(int));
for (int i = 0; i <cityNumber; i++)
{
city_divided[i] = City[(my_rank-1)*cityNumber + 1];
}
}
}else{
cityNumber = N / (nthreads - 1);
city_divided = (int*)malloc(cityNumber*sizeof(int));
for (int i = 0; i <cityNumber; i++)
{
city_divided[i] = City[(my_rank-1)*cityNumber + 1];
}
}
if(my_rank==0){
MPI_Recv(&ans, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
for(int i=0;i<N;i++){
if(i != N-1){
printf("%d,",*(result+i));
}
else{
printf("%d",*(result+i));
}
}
printf("\n");
printf("Distance: %d\n",ans);
}
if(my_rank!=0){
for (int i = 0 ; i<cityNumber;i++){
current_ans = ans;
while(s.isEmpty(s)){
MPI_Recv(&ans, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
result = tsp(Dis,v,N,1,city_divided[i],0,ans,result,temp,log);
s.Pop(&s,ans);
}
result = tsp(Dis,v,N,1,city_divided[i],0,ans,result,temp,log);
if(current_ans - ans > 0){
s.Push(ans);
MPI_Bcast(&ans,1,MPI_INT,0,MPI_COMM_WORLD);
}
}
}
}
else{
result = tsp(Dis,v,N,1,1,0,sum,result,temp,log);
}
for(int i=0;i<N;i++){
if(i != N-1){
printf("%d,",*(result+i));
}
else{
printf("%d",*(result+i));
}
}
printf("\n");
printf("Distance: %d\n",ans);
return 0;
}
I am trying to solve a special travelling salesman problem with mpi and c. I want make the master processor print the final information including the route and the shorest distance. the other processors with all city group run the tsp function, and when it has the shorter distance, use mpi_send or mpi_Bcast to other processors.Follow this logic, I meet a problem when I run the program.
enter image description here

design an algorithm to determine whether there exists such a key which is equal to the summation of other two keys in the array

i'm trying to solve this problem: given an array containing n keys determine whether there exists such a key that is equal to sum of other two keys in array. if yes, print them out.
I'm using mergesort to sort the array and then checking for keys. but (for loop) inside summation function somehow fails to increment every time. i've tried (while loop) and several other ways. nothing works. any ideas?
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
void merge_sort(int input_array[], int first_element, int last_element);
void merge(int input_array[], int first_element, int middle_element,
int last_element);
void find_summation(int input_array[], int first_element, int last_element);
int total_elements;
int main() {
int input_array[100];
printf("\nEnter number of elements in the array : ");
scanf("%d", &total_elements);
int i = 0;
printf("\nEnter %d array elements: ", total_elements);
while (i < total_elements) {
scanf("%d", &input_array[i]);
i++;
}
merge_sort(input_array, 0, total_elements - 1);
printf("\nSorted Array: ");
for (int i = 0; i < total_elements; i++) {
printf("%d ", input_array[i]);
}
printf("\n");
find_summation(input_array, 0, total_elements - 1);
printf("\n");
return 0;
}
void find_summation(int input_array[], int first_element, int last_element) {
bool found;
last_element = total_elements - 1;
int j = 2;
int current_num;
for (int j = 2; j <= last_element;) {
current_num = input_array[j];
while ((first_element < last_element)) {
int a = input_array[first_element];
int b = input_array[last_element];
int summation = a + b;
printf("summation %d\n", summation);
if (summation == current_num) {
found = true;
} else if (summation > current_num) {
last_element--;
} else if (summation < current_num) {
first_element++;
}
if (found) {
printf("\nKey: %d > sum of Keys: %d & %d", current_num, a,
current_num - a);
break;
}
}
}
}
void merge(int input_array[], int first_element, int middle_element,
int last_element) {
int m = (middle_element - first_element) + 1;
int n = last_element - middle_element;
int left_array[m];
int right_array[n];
for (int i = 0; i < m; i++) {
left_array[i] = input_array[first_element + i];
}
for (int j = 0; j < n; j++) {
right_array[j] = input_array[(middle_element + 1) + j];
}
int i = 0, j = 0, k = 0;
k = first_element;
while (i < m && j < n) {
if (left_array[i] <= right_array[j]) {
input_array[k] = left_array[i++];
} else {
input_array[k] = right_array[j++];
}
k++;
}
while (i < m) {
input_array[k++] = left_array[i++];
}
while (j < n) {
input_array[k++] = right_array[j++];
}
}
void merge_sort(int input_array[], int first_element, int last_element) {
if (first_element < last_element) {
int middle_element = (first_element + last_element) / 2;
merge_sort(input_array, first_element, middle_element);
merge_sort(input_array, middle_element + 1, last_element);
merge(input_array, first_element, middle_element, last_element);
} else
return;
}
Thank you everyone for guidance and support. Finally got the code to work on all the cases. original code had a lot of mistakes. including control flow and logical errors. i have fixed the code now. solution is posted below:
Test Case: 18 23 4 35 99 67 198 20 38 55 2 19 487 11 40 10 13 27 22
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
void merge_sort(int input_array[], int first_element, int last_element);
void merge(int input_array[], int first_element, int middle_element,
int last_element);
void find_summation(int input_array[], int first_element, int last_element);
int binary_search(int input_array[], int first_element, int last_element,
int difference);
int main() {
int total_elements;
int input_array[100];
printf("\nEnter number of elements in the array : ");
scanf("%d", &total_elements);
int i = 0;
printf("\nEnter %d array elements: ", total_elements);
while (i < total_elements) {
scanf("%d", &input_array[i]);
i++;
}
merge_sort(input_array, 0, total_elements - 1);
printf("\nSorted Array: ");
for (int i = 0; i < total_elements; i++) {
printf("%d ", input_array[i]);
}
printf("\n");
find_summation(input_array, 0, total_elements);
printf("\n");
return 0;
}
void find_summation(int input_array[], int first_element, int last_element) {
for (int j = 0; j <= last_element; j++) {
int current_num = input_array[j];
// printf("current_num and j: %d %d\n", current_num, j);
for (int i = 0; i < j; i++) {
int element = input_array[i];
int element_found =
binary_search(input_array, first_element, j, (current_num - element));
if (element_found > 0) {
if (element != (current_num - element))
printf("\nKey: %d > sum of Keys: %d & %d", current_num, element,
current_num - element);
}
}
}
}
int binary_search(int input_array[], int first_element, int last_element,
int difference) {
bool found;
int current_num;
int middle_element = (first_element + last_element) / 2;
if ((last_element >= first_element) && (first_element < middle_element)) {
// int middle_element = (first_element + last_element) / 2;
/*
while ((last_element - first_element) <= 2) {
return binary_search(input_array, middle_element + 1, last_element,
difference);
}*/
if (input_array[middle_element] == difference) {
return middle_element;
}
if (input_array[middle_element] > difference) {
return binary_search(input_array, first_element, middle_element - 1,
difference);
}
return binary_search(input_array, middle_element + 1, last_element,
difference);
}
return -1;
}
void merge(int input_array[], int first_element, int middle_element,
int last_element) {
int m = (middle_element - first_element) + 1;
int n = last_element - middle_element;
int left_array[m];
int right_array[n];
for (int i = 0; i < m; i++) {
left_array[i] = input_array[first_element + i];
}
for (int j = 0; j < n; j++) {
right_array[j] = input_array[(middle_element + 1) + j];
}
int i = 0, j = 0, k = 0;
k = first_element;
while (i < m && j < n) {
if (left_array[i] <= right_array[j]) {
input_array[k] = left_array[i++];
} else {
input_array[k] = right_array[j++];
}
k++;
}
while (i < m) {
input_array[k++] = left_array[i++];
}
while (j < n) {
input_array[k++] = right_array[j++];
}
}
void merge_sort(int input_array[], int first_element, int last_element) {
if (first_element < last_element) {
int middle_element = (first_element + last_element) / 2;
merge_sort(input_array, first_element, middle_element);
merge_sort(input_array, middle_element + 1, last_element);
merge(input_array, first_element, middle_element, last_element);
} else
return;
}

2d / multidimensional array char

Here is my code
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main ()
{
int i,k;
char a[4][2] = { {'*','*'}, {'*','*'}, {'*','*'}, {'*','*'}};
/* output each array element's value */
for ( i = 0; i < 4; i++ ) {
for ( k = 0; k < 2; k++ ) {
printf("%c ", a[i][k] );
}
printf("\n");
}
return 0;
}
I would like to know how to replace a character from a 2d array with another character with user input? for example if the user wants to replace the asterisk at [0][0] with an F the output would look like this:
F *
* *
* *
* *
`
I would really appreciate it because I can't seem to find any example of this anywhere. Thanks
int main ()
{
int i,k,row,column;
char a[4][2] = { {'*','*'}, {'*','*'}, {'*','*'}, {'*','*'}},rc;
// before replace
printf("Before Replace :\n");
for ( i = 0; i < 4; i++ ) {
for ( k = 0; k < 2; k++ ) {
printf("%c ", a[i][k] );
}
printf("\n");
}
printf("Enter a Character you want to Replace : ");
scanf("%c",&rc);
printf("Enter row and column Index: ");
scanf("%d%d",&row,&column);
for ( i = 0; i < 4; i++ ) {
for ( k = 0; k < 2; k++ ) {
if(i==row && k==column){
a[i][k]=rc;
}
}
}
printf("\nAfter replace :\n");
for ( i = 0; i < 4; i++ ) {
for ( k = 0; k < 2; k++ ) {
printf("%c ", a[i][k] );
}
printf("\n");
}
return 0;
}

Can't free memory from 2D dynamical array

I am having problem with freeing my memory. I did this many times, and it was working fine. Now, it just stops working (no error, anything, just freeze).
How my code looks like:
void args(int argc, char** argv, int *n, int *m, int **matrix, char name[20])
{
int firstIter = TRUE;
int x;
char op;
int** second;
second = NULL;
op = argv[1][0];
for (x = 2; x < argc; x++)
{
if (!firstIter)
{
setName(name, argv[x]);
loadMatrix(*m, *n, second, *name);
opMatrix(*m, *n, matrix, second, &*matrix, op);
}
else
{
setName(name, argv[x]);
loadSizeMatrix(n, m, name);
matrix = (int **)malloc(*n * sizeof(int*));
for (int i = 0; i < *n; i++) {
matrix[i] = (int *)malloc(*m * sizeof(int));
}
second = (int **)malloc(*n * sizeof(int*));
for (int i = 0; i < *n; i++) {
second[i] = (int *)malloc(*m * sizeof(int));
}
loadMatrix(*m, *n, matrix, *name);
firstIter = FALSE;
}
}
printMatrix(*m, *n, matrix);
for (int i = 0; i < *n; i++) {
free(second[i]);
}
free(second[0]); //doesnt work too, and yes, there are data
free(second);
}
second is being filled like this (loadMatrix):
for (int c = 0; c < radky; c++) {
for (int d = 0; d < sloupce; d++) {
fscanf(fp, "%i", &second[c][d]);
// printf("%i", matice[c][d]); // dump
}
}
How can I solve this error?
my full code
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <ctype.h> //tolower
#include <string.h>
#define TRUE 1
#define FALSE !TRUE
/* konstanty */
const enum {
MAX_DELKA_SOUBORU = 10000,
MAX_SOUBOR = 20
};
const enum {
SOUBOR_NENALEZEN = 1,
SPATNE_ARGUMENTY = 2,
LIMIT_NAZEV_SOUBOR = 3,
SPATNY_OP = 4
};
void error(int type);
void zpracovaniArgumentu(int argc, char** argv, char(*nazevSouboru)[MAX_SOUBOR], char(*nazevVystupni)[MAX_SOUBOR], int *n, int *m, int **matice);
void setNazevSouboru(char(*nazev)[MAX_SOUBOR], char *argument);
void vypisMatice(int radky, int sloupce, int **matice);
int nacteniMaticeZeSouboru(int radky, int sloupce, int **matice, char nazev[MAX_SOUBOR]);
int nacteniVelikostiMatice(int *n, int *m, char nazev[MAX_SOUBOR]);
int operaceMatic(int radky, int sloupce, int **prvni, int **druha, int **vysledek, char op);
int main(int argc, char** argv)
{
int n, m; // n = sloupce, m = radky pro prvni matici
int** first;
char nazevSouboru[MAX_SOUBOR], nazevVystupni[MAX_SOUBOR];
char op;
first = NULL;
zpracovaniArgumentu(argc, argv, &nazevSouboru, &nazevVystupni, &n, &m, &*first);
/* for (int i = 0; i < m; i++) {
free(first[i]);
} */
free(first);
system("pause");
return 0;
}
void error(int type)
{
switch (type)
{
case SOUBOR_NENALEZEN: printf("Soubor nenalezen!");
break;
case SPATNE_ARGUMENTY: printf("Program spustte s argumenty [nazev souboru] *[nazev vystupniho souboru]*.\n");
break;
case MAX_DELKA_SOUBORU: printf("Prekrocen maximalni limit delky nazvu souboru (%i).\n", MAX_SOUBOR);
break;
case SPATNY_OP: printf("Program spustte s argumenty [nazev souboru] *[nazev vystupniho souboru]*.\n");
break;
default: printf("Nastala chyba!");
break;
}
system("pause");
exit(type);
}
void zpracovaniArgumentu(int argc, char** argv, char(*nazevSouboru)[MAX_SOUBOR], char(*nazevVystupni)[MAX_SOUBOR], int *n, int *m, int **matice)
{
int firstIter = TRUE;
int doSouboru = FALSE;
int x;
char op;
int** second;
second = NULL;
op = argv[1][0];
for (x = 2; x < argc; x++)
{
if (!firstIter)
{
setNazevSouboru(nazevSouboru, argv[x]);
nacteniMaticeZeSouboru(*m, *n, &*second, *nazevSouboru);
operaceMatic(*m, *n, matice, &*second, &*matice, op);
}
else if (argv[x][0] == '-')
{
switch (argv[x][1])
{
case 'n': doSouboru = TRUE;
break;
default: error(SPATNE_ARGUMENTY);
break;
}
}
else if (doSouboru)
{
setNazevSouboru(nazevVystupni, argv[x]);
}
else
{
setNazevSouboru(nazevSouboru, argv[x]);
nacteniVelikostiMatice(n, m, *nazevSouboru);
matice = (int **)malloc(*n * sizeof(int*));
for (int i = 0; i < *n; i++) {
matice[i] = (int *)malloc(*m * sizeof(int));
}
second = (int **)malloc(*n * sizeof(int*));
for (int i = 0; i < *n; i++) {
second[i] = (int *)malloc(*m * sizeof(int));
}
nacteniMaticeZeSouboru(*m, *n, &*matice, *nazevSouboru);
firstIter = FALSE;
}
}
vypisMatice(*m, *n, matice);
for (int i = 0; i < *n; i++) {
printf("%i",second[i]);
free(second[i]);
}
free(second);
}
void setNazevSouboru(char(*nazev)[MAX_SOUBOR], char *argument)
{
strcpy(*nazev, argument);
strcat(*nazev, ".txt"); //nazev souboru
}
int nacteniVelikostiMatice(int *n, int *m, char nazev[MAX_SOUBOR])
{
FILE *fp = fopen(nazev, "r"); // načtení souboru
int c;
int radky = 1;
int sloupce = 0;
if (!fp)
{
error(SOUBOR_NENALEZEN);
exit(2);
}
else
{
while ((c = fgetc(fp)) != EOF)
{
//tolower(c);
if (c == '\n')
{
radky++;
}
else if ((isdigit(c)) && (radky == 1))
{
sloupce++;
}
}
}
fclose(fp);
*n = sloupce;
*m = radky;
return 0;
}
int nacteniMaticeZeSouboru(int radky, int sloupce, int **matice, char nazev[MAX_SOUBOR])
{
int x;
FILE *fp = fopen(nazev, "r"); // načtení souboru
if (!fp)
{
error(SOUBOR_NENALEZEN);
exit(2);
}
else
{
for (int c = 0; c < radky; c++) {
for (int d = 0; d < sloupce; d++) {
fscanf(fp, "%i", &matice[c][d]);
// printf("%i", matice[c][d]); // dump
}
}
}
fclose(fp);
return 0;
}
int operaceMatic(int radky, int sloupce, int **prvni, int **druha, int **vysledek, char op)
{
int vysledekClip[10][10];
for (int c = 0; c < radky; c++) {
for (int d = 0; d < sloupce; d++) {
switch (op) {
case '+': vysledekClip[c][d] = prvni[c][d] + druha[c][d];
vysledek[c][d] = vysledekClip[c][d];
break;
case '-': vysledekClip[c][d] = prvni[c][d] - druha[c][d];
vysledek[c][d] = vysledekClip[c][d];
break;
case '/': vysledekClip[c][d] = prvni[c][d] / druha[c][d];
vysledek[c][d] = vysledekClip[c][d];
break;
case '%': vysledekClip[c][d] = prvni[c][d] % druha[c][d];
vysledek[c][d] = vysledekClip[c][d];
break;
case '*': vysledekClip[c][d] = prvni[c][d] * druha[c][d];
vysledek[c][d] = vysledekClip[c][d];
break;
default: error(SPATNY_OP);
break;
}
vysledek[c][d] = vysledekClip[c][d];
}
}
return 0;
}
void vypisMatice(int radky, int sloupce, int **matice)
{
int c;
int d;
for (c = 0; c < radky; c++) {
for (d = 0; d < sloupce; d++) {
printf("%i\t", matice[c][d]);
} printf("\n");
}
}
void vypisMaticeDoSouboru(int radky, int sloupce, int **matice, char nazevSouboru[MAX_DELKA_SOUBORU])
{
int c;
int d;
for (c = 0; c < radky; c++) {
for (d = 0; d < sloupce; d++) {
printf("%i\t", matice[c][d]);
} printf("\n");
}
}
You have a problem with the 'second' array. You allocate an array of *n pointers to int but fill *m elements in that array:
second = (int **) malloc(*n * sizeof(int*));<p>
for (int i = 0; i < *m; i++) {

Pointers and Dynamic Memory

I have a function that returns a pointer to an array. I'm running it in a loop and free() seems to be giving me problems. I'm not sure where, but it appears that somewhere in the main loop the memory that I'm trying to free is being used. I'm using Xcode 3.2.1 in 10.6 | Debug | x86_64 build.
The program will run through the main loop one time; the second time it encounters the free() it gives me the following error:
malloc: *** error for object 0x100100180: incorrect checksum for freed object -
object was probably modified after being freed.
Can someone point out (no pun intended) what I'm doing wrong with pointers here?
Here is the program:
int main(int argc, char **argv) {
int *partition;
int lowerLimit;
int upperLimit;
// snip ... got lowerLimit and upperLimit from console arguments
// this is the 'main loop':
for (int i = lowerLimit; i <= upperLimit; i += 2) {
partition = goldbachPartition(i);
printOutput(partition[0], partition[1], i);
free(partition); // I get problems on the second iteration here
}
return 0;
}
int *goldbachPartition(int x) {
int solved = 0;
int y, z;
int *primes;
int *result;
result = intAlloc(2);
primes = atkinsPrimes(x);
for (int i = intCount(primes)-1; i >= 0; i--) {
y = primes[i];
for (int j = 0; j < y; j++) {
z = primes[j];
if (z + y >= x) {
break;
}
}
if (z + y == x) {
solved = 1;
result[0] = y;
result[1] = z;
break;
} else if (y == z) {
result[0] = 0;
result[1] = 0;
break;
}
}
free(primes);
return result;
}
int *atkinsPrimes(int limit) {
int *primes;
int *initialPrimes;
int *filtered;
int *results;
int counter = 0;
int sqrtLimit;
int xLimit;
int resultsSize;
primes = intAlloc(limit+1);
intFillArray(primes, limit+1, 0);
sqrtLimit = floor(sqrt(limit));
xLimit = floor(sqrt((limit+1) / 2));
// these loops are part of the Atkins Sieve implementation
for (int x = 1; x < xLimit; x++) {
int xx = x*x;
for (int y = 1; y < sqrtLimit; y++) {
int yy = y*y;
int n = 3*xx + yy;
if (n <= limit && n % 12 == 7) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
n += xx;
if (n <= limit && (n % 12 == 1 || n % 12 == 5)) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
if (x > y) {
n -= xx + 2*yy;
if (n <= limit && n % 12 == 11) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
}
}
}
for (int n = 5; n < limit; n++) {
if (primes[n] == 1) {
for (int k = n*n; k < limit; k += n*n) {
primes[k] = 0;
}
}
}
initialPrimes = intAlloc(2);
if (limit >= 2) {
initialPrimes[counter++] = 2;
}
if (limit >= 3) {
initialPrimes[counter++] = 3;
}
filtered = intFilterArrayKeys(primes, limit+1);
results = intMergeArrays(initialPrimes, filtered, counter, trueCount(primes, limit+1));
resultsSize = counter + trueCount(primes, limit+1);
free(primes);
free(initialPrimes);
free(filtered);
results[resultsSize] = 0;
return results;
}
int trueCount(int *subject, int arraySize) {
int count = 0;
for (int i = 0; i < arraySize; i++) {
if (subject[i] == 1) {
count++;
}
}
return count;
}
int intCount(int *subject) {
// warning: expects 0 terminated array.
int count = 0;
while (*subject++ != 0) {
count++;
}
return count;
}
void intFillArray(int *subject, int arraySize, int value) {
for (int i = 0; i < arraySize; i++) {
subject[i] = value;
}
}
int *intFilterArrayKeys(int *subject, int arraySize) {
int *filtered;
int count = 0;
filtered = intAlloc(trueCount(subject, arraySize));
for (int i = 0; i < arraySize; i++) {
if (subject[i] == 1) {
filtered[count++] = i;
}
}
return filtered;
}
int *intMergeArrays(int *subject1, int *subject2, int arraySize1, int arraySize2) {
int *merge;
int count = 0;
merge = intAlloc(arraySize1 + arraySize2);
for (int i = 0; i < arraySize1; i++) {
merge[count++] = subject1[i];
}
for (int i = 0; i < arraySize2; i++) {
merge[count++] = subject2[i];
}
return merge;
}
int *intAlloc(int amount) {
int *ptr;
ptr = (int *)malloc(amount * sizeof(int));
if (ptr == NULL) {
printf("Error: NULL pointer\n");
}
return ptr;
}
void printOutput(int num1, int num2, int rep) {
if (num1 == 0) {
printf("%d: No solution\n", rep);
exit(0);
} else {
printf("%d = %d + %d\n", rep, num1, num2);
}
}
Why is intAlloc not returning int* ?
int *intAlloc(int amount) {
int *ptr;
ptr = (int *)malloc(amount * sizeof(int));
if(ptr == NULL) {
printf("Error: NULL pointer\n");
exit(1);
}
return ptr; //like this
}
EDIT (after your update):
On atkinsPrimes() where is filtered being intAlloc()ed?
int *atkinsPrimes(int limit) {
int *primes;
int *initialPrimes;
int *filtered;
int *results;
int resultsSize;
primes = intAlloc(limit+1);
// ...
initialPrimes = intAlloc(2);
// ...
resultsSize = counter + trueCount(primes, limit+1);
free(primes);
free(initialPrimes);
free(filtered); // Where was it intAlloc()ed?
results[resultsSize] = 0; // make the array 0-terminated to make it easier to work with
return results;
}
EDIT (after your N-th update):
This is a compilable version of your code. It ran smooth on my machine, no crashes. Compiled with g++ (due to declarations of variables inside the for statement):
g++ (Debian 4.3.2-1.1) 4.3.2
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int *goldbachPartition(int x);
int *atkinsPrimes(int limit);
int trueCount(int *subject, int arraySize);
int intCount(int *subject) ;
void intFillArray(int *subject, int arraySize, int value);
int *intFilterArrayKeys(int *subject, int arraySize);
int *intAlloc(int amount);
void printOutput(int num1, int num2, int rep) ;
int *intMergeArrays(int *subject1, int *subject2, int arraySize1, int arraySize2);
int main(int argc, char **argv) {
if (argc < 3) {
printf("Usage: ./program <lower> <upper>\n");
return 0;
}
int *partition;
int lowerLimit = atoi(argv[1]);
int upperLimit = atoi(argv[2]);
// snip ... got lowerLimit and upperLimit from console arguments
// this is the 'main loop':
for (int i = lowerLimit; i <= upperLimit; i += 2) {
partition = goldbachPartition(i);
printOutput(partition[0], partition[1], i);
free(partition); // I get problems on the second iteration here
}
return 0;
}
int *goldbachPartition(int x) {
int solved = 0;
int y, z;
int *primes;
int *result;
result = intAlloc(2);
primes = atkinsPrimes(x);
for (int i = intCount(primes)-1; i >= 0; i--) {
y = primes[i];
for (int j = 0; j < y; j++) {
z = primes[j];
if (z + y >= x) {
break;
}
}
if (z + y == x) {
solved = 1;
result[0] = y;
result[1] = z;
break;
} else if (y == z) {
result[0] = 0;
result[1] = 0;
break;
}
}
free(primes);
return result;
}
int *atkinsPrimes(int limit) {
int *primes;
int *initialPrimes;
int *filtered;
int *results;
int counter = 0;
int sqrtLimit;
int xLimit;
int resultsSize;
primes = intAlloc(limit+1);
intFillArray(primes, limit+1, 0);
sqrtLimit = floor(sqrt(limit));
xLimit = floor(sqrt((limit+1) / 2));
for (int x = 1; x < xLimit; x++) {
int xx = x*x;
for (int y = 1; y < sqrtLimit; y++) {
int yy = y*y;
int n = 3*xx + yy;
if (n <= limit && n % 12 == 7) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
n += xx;
if (n <= limit && (n % 12 == 1 || n % 12 == 5)) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
if (x > y) {
n -= xx + 2*yy;
if (n <= limit && n % 12 == 11) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
}
}
}
for (int n = 5; n < limit; n++) {
if (primes[n] == 1) {
for (int k = n*n; k < limit; k += n*n) {
primes[k] = 0;
}
}
}
initialPrimes = intAlloc(2);
if (limit >= 2) {
initialPrimes[counter++] = 2;
}
if (limit >= 3) {
initialPrimes[counter++] = 3;
}
filtered = intFilterArrayKeys(primes, limit+1);
results = intMergeArrays(initialPrimes, filtered, counter, trueCount(primes, limit+1));
resultsSize = counter + trueCount(primes, limit+1);
free(primes);
free(initialPrimes);
free(filtered);
results[resultsSize] = 0;
return results;
}
int trueCount(int *subject, int arraySize) {
int count = 0;
for (int i = 0; i < arraySize; i++) {
if (subject[i] == 1) {
count++;
}
}
return count;
}
int intCount(int *subject) {
// warning: expects 0 terminated array.
int count = 0;
while (*subject++ != 0) {
count++;
}
return count;
}
void intFillArray(int *subject, int arraySize, int value) {
for (int i = 0; i < arraySize; i++) {
subject[i] = value;
}
}
int *intFilterArrayKeys(int *subject, int arraySize) {
int *filtered;
int count = 0;
filtered = intAlloc(trueCount(subject, arraySize));
for (int i = 0; i < arraySize; i++) {
if (subject[i] == 1) {
filtered[count++] = i;
}
}
return filtered;
}
int *intMergeArrays(int *subject1, int *subject2, int arraySize1, int arraySize2) {
int *merge;
int count = 0;
merge = intAlloc(arraySize1 + arraySize2);
for (int i = 0; i < arraySize1; i++) {
merge[count++] = subject1[i];
}
for (int i = 0; i < arraySize2; i++) {
merge[count++] = subject2[i];
}
return merge;
}
int *intAlloc(int amount) {
int *ptr;
ptr = (int *)malloc(amount * sizeof(int));
if (ptr == NULL) {
printf("Error: NULL pointer\n");
}
return ptr;
}
void printOutput(int num1, int num2, int rep) {
if (num1 == 0) {
printf("%d: No solution\n", rep);
exit(0);
} else {
printf("%d = %d + %d\n", rep, num1, num2);
}
}
Since you are still omitting some source, I can only imagine that the problem is hidden there.
EDIT: (my last update)
To assist your debugging, you should replace your main() function by the one below:
int main(int argc, char **argv)
{
int *primes = NULL;
primes = atkinsPrimes(44); // Evil magic number
free(primes);
return 0;
}
Having a minimal example to reproduce the behavior you pointed out is much better then the whole thing. Have fun with atkinsPrimes(44)

Resources