I'm working on this quite simple C program, wich builds an histogram from an array. What it does in particular, is writing on a second array the ciphres of the first array, followed by the number of their occurences. For instance: if the array A is {2,3,2,5,6,6,6} the array histogram of A, will be {2,2,3,1,5,1,6,3}. Ok, so my program compiles well and there aren't any warnings or errors. But the program stops working after i' ve inserted the values of array A. Where am i failing??? Thank you!!
typedef unsigned short int boolean;
#define TRUE 1
#define FALSE 0
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <conio.h>
boolean Array_Histogram(int *A, int N, int **H, int *count){
int i,j;
boolean found;
*H = (int *) malloc( sizeof(int)*2*N );
if(*H==NULL)
return FALSE;
(*count)=0;
for(i=0;i<N;i++){
found=FALSE;
j=0;
while(found==FALSE && j<(*count)*2){
if(A[i]==(*H[j]))
found=TRUE;
else j+=2;
}
if(found==TRUE){
(*H)[j+1]++;
}
else{
(*H)[j] = A[i];
(*H)[j+1] = 1;
(*count) ++;
}
}
return TRUE;
}
int main(){
int N;
int count;
int *A;
int **H;
int *i;
i=0;
printf("Inserisci N, dimensione dell'array A:");
scanf("%d", &N);
if(N<=0){
return 0;
}
A= (int*) malloc (sizeof(int)*N);
*H = (int *) malloc( sizeof(int)*2*N );
for(count=0;count<N;count++){
printf("\n Inserisci il valore %d di A:", count);
scanf("%d", &A[count]);
}
Array_Histogram(A,N,H,i);
printf("\nI valori dell'istogramma sono:");
for(count=0;count<2*N;count++)
printf("\n %d", (*H)[count]);
return 0;
}
The variable H in main is of the wrong type. It should be declared:
int *H;
You need to change 2 more lines in main with regards to this:
H = malloc( sizeof(int)*2*N );
and
Array_Histogram(A,N,&H,i);
Also, you need to allocate H only once.
I am not really sure what are you trying to achieve but your problem is de-referencing null pointer.
H is double pointer to integer. so you have to allocate memory to H using malloc before using *H
int **H;
*H = malloc( sizeof(int)*2*N );
Edit:
Suggest you to read some basics about pointer here
You are allocating memory for H twice(once in main, once in the func).
H is declared as int **, memory is being allocated to 2*N elements of integer pointers each, which is probably not what you wanted to do.
If you just want output as {2,2, 3,1..}, then probably you just want a int *H;
Related
I am relatively new to C. My program is supposed to fill in the array with random numbers and i have to find the max and min using 1 function. The program works fine up until the point i have to return the values my 2 pointers get from the function. When i go to print them the porgram stop working and exits with the return value of 3221225477. I have been trying to fix this for 3 hours and i am going INSANE. Please help in any way you can i would really apreciate it.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void MaxMin(int size, int *B, int *Max, int *Min);
int main(int argc, char *argv[])
{
int N, i,*A,*MAX,*MIN;
srand(time(NULL));
/*Making sure the user enters a proper value for the array*/
do
{
printf("Give the number of spaces in the Array\n");
scanf("%d",&N);
}
while(N<1);
A = (int *) malloc(N*(sizeof(N)));
/*Giving random numbers to the array and printing them so i can make sure my code is finding the max min*/
for(i=0;i<N;i++)
{
A[i]=rand()%100;
printf("\n%d\n",A[i]);
}
/*Calling my void function so that the pointers MAX and MIN have a value assigned to them */
MaxMin(N, A, MAX, MIN);
/*Printing them*/
printf("\nMax = %d\nMin = %d",*MAX,*MIN);
free(A);
return 0;
}
/*The function*/
void MaxMin(int size, int *B, int *Max, int *Min)
{
/*using 2 temporary ints to get max min cause pointers and arrays confuse me*/
int max=B[0],min=B[0],i;
for(i=1;i<size;i++)
{
if(max<B[i])
{
max = B[i];
}
if(min>B[i])
{
min = B[i];
}
}
/*These have the proper value last i chekced */
Max = &max;
Min = &min;
}
(edit) SOLUTION Ty so much for the help !
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void MaxMin(int size, int *B, int *Max, int *Min);
int main(int argc, char *argv[])
{
int N, i,*A,MAX ,MIN ;
srand(time(NULL));
/*Making sure the user enters a proper value for the array*/
do
{
printf("Give the number of spaces in the Array\n");
scanf("%d",&N);
}
while(N<1);
A = (int *) malloc(N*(sizeof(int)));
/*Giving random numbers to the array and printing them so i can make sure my code is finding the max min*/
for(i=0;i<N;i++)
{
A[i]=rand()%100;
printf("\n%d\n",A[i]);
}
/*Calling my void function so that the pointers MAX and MIN have a value assigned to them */
MaxMin(N, A, &MAX, &MIN);
/*Printing them*/
printf("\nMax = %d\nMin = %d",MAX,MIN);
free(A);
return 0;
}
/*The function*/
void MaxMin(int size, int *B, int *Max, int *Min)
{
*Max=B[0];
*Min=B[0];
int i;
for(i=1;i<size;i++)
{
if(*Max<B[i])
{
*Max = B[i];
}
if(*Min>B[i])
{
*Min = B[i];
}
}
}
You passed to the function MaxMin pointers MAX and MIN by value. That is the function deals with copies of (indeterminate) values of the passed pointers. Changing the copies does not influence on the original arguments.
Within main you should declare MIN and MAX as objects of the type int.
int N, i,*A, MAX, MIN;
and call the function ,like
MaxMin(N, A, &MAX, &MIN);
Within the function you should write
*Max = &max;
*Min = &min;
And at last in main you should call printf like
printf("\nMax = %d\nMin = %d", MAX, MIN);
Pay attention to that the expression sizeof( N ) used in this statement
A = (int *) malloc(N*(sizeof(N)));
is error prone. The type of the variable N can be changed for example from the type int to the type size_t. In this case the size of the allocated memory will be incorrect, You should write for example
A = (int *) malloc(N*(sizeof( *A )));
You have three bugs:
In main, you don't assign MAX or MIN any values. So you pass garbage to MaxMin.
In MaxMin, Max and Min are about to go out of scope. Changing their values before they go out of scope has no effect on anything.
In main, you don't create any place to hold the maximum and minimum values. So where are you expecting them to be stored?
So I have a program in C structured in 3 files: main.c, alloc.h and alloc.c. In the main.c function, I have the declaration of a pointer to another pointer to which I intend to alloc an n * m array:
#include <stdio.h>
#include <stdlib.h>
#include "alloc.h"
int main() {
int **mat, n, m;
alloc_matrix(&mat, int &n, int &m);
return 0;
}
In alloc.c I have the following declarations:
#ifndef ALLOC_H_INCLUDED
#define ALLOC_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
void alloc_matrix(int***, int*, int*);
#endif
In alloc.c I have the function:
void alloc_matrix(int ***mat, int *n, int *m) {
printf("\nn = "); scanf("%d", n);
printf("\nm = "); scanf("%d", m);
*mat = (int**)calloc(*n, sizeof(int*));
int i;
for (i = 0; i < *n; i++)
*(mat + i) = (int*)calloc(*m, sizeof(int));
}
But the program doesn't work. It enters some kind of loop and doesn't end.
If I allocate it in main it would work but I have no idea what I am doing wrong in the alloc function.
Here is the correct code. Your error was that in the definition of alloc_matrix, you used *(mat+i) in the allocation loop, which should be *(*mat+i) as, mat is a int*** so the base address for the 2D array would be in *mat. Then you need to move by offset i and then de-reference that memory location for the 1D array.
Main:
#include <stdio.h>
#include <stdlib.h>
#include "alloc.h"
int main()
{
int **mat,n,m;
alloc_matrix(&mat,&n,&m);
return 0;
}
alloc.h
#ifndef ALLOC_H_INCLUDED
#define ALLOC_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
void alloc_matrix(int***,int*,int*);
#endif
alloc.c :
void alloc_matrix(int ***mat,int *n,int *m)
{
printf("\nn = "); scanf("%d", n);
printf("\nm = "); scanf("%d", m);
*mat = (int**)calloc(*n,sizeof(int*));
int i;
for(i = 0; i < *n; i++)
*(*mat+i) = (int*)calloc(*m,sizeof(int));
}
The code for the read function :
void read_matrix(int ***mat,int n,int m)
{
int i,j;
for(i = 0; i < n; i++)
for(j = 0; j < m; j++)
{
printf("mat[%d][%d] = ", i, j);
scanf("%d", (*(*mat+i))+j);
}
}
The problem with it is that it only reads the first row and the it freezes.
void alloc_matrix(int ***mat,int *n,int *m)
There are two problems in this line. Neither is fatal but both are worth fixing.
First problem: A matrix in this program is represented as an int**. Why does alloc_matrix accept an int***? All standard functions that allocate something (malloc and friends) return a pointer to that something. This is an idiomatic way of doing things in C. It reduces your star count (being a three-star C programmer is not an achievement to be proud of) and simplifies the code. The function should be changed to
int** alloc_matrix( // but what's inside the () ?
The second problem is, why should a function called alloc_matrix prompt the user and read values? These things are not related to allocation. A function should do one thing and do it well. Does malloc prompts you to enter the size? Does fopen prompt you to enter the filename? These things would be regarded as nonsense of the first degree, and rightly so. It is advised to read the sizes elsewhere and pass them to alloc_matrix as input arguments. Hence,
int** alloc_matrix(int n, int m) { // but what's inside the {}?
What remains of alloc_matrix is simple:
int** alloc_matrix(int n, int m) {
int** mat; // that's what we will return
int i;
mat = (int**)calloc(n, sizeof(int*));
for(i = 0; i < n; i++)
// here comes the important part.
Since we have simplified alloc_matrixand reduced the star count in mat, what should we do with the old body of the loop? It was:
*(mat+i) = (int*)calloc(...);
but if we remove a star, it becomes
(mat+i) = (int*)calloc(...);
which is an obvious nonsense. Perhaps the old line was a problem. The fact that it provoked a compiler warning certainly doesn't speak for its correctness. So how to correct it? There aren't too many options. It turns out that in order to restore sanity, we must leave the old left-hand side (written for the three-star mat) intact. Or, better still, use an equivalent but more idiomatic notation:
mat[i] = (int*)calloc(m, sizeof(int));
So the entire function now becomes
int** alloc_matrix(int n, int m) {
int **mat;
int i;
mat = (int**)calloc(n, sizeof(int*));
for(i = 0; i < n; i++)
mat[i] = (int*)calloc(m, sizeof(int));
return mat;
}
and it should be called like
mat = alloc_matrix(n, m);
It is often said that one should not cast the result of calloc and friends. But in this case the cast has enabled a warning which helped to find a bug. I'm leaving the casts in place for now.
There is another idiom for the allocation that does not require the cast, but also avoids the problem of types not matching.
Instead of using the type for the sizeof, you can use the dereferenced pointer as the type information is available in the variable:
mat = (int**)calloc(n, sizeof(int*));
can be changed to
mat = calloc(n, sizeof *mat); //sizeof is an operator not a function
So I am now rewriting my fortran code in C (to use CUDA), and apparently I do not understand how to properly use malloc and pointers. I am trying to make the main function just calls to other functions, which need to malloc arrays that will then be used inside other functions. So, I am passing pointers of pointers to them as per this post: C Programming: malloc() inside another function
But the right amount of memory is not being allocated so I get segmentation faults. Here is the code:
#include <stdio.h>
#include <stdlib.h>
//#include <cuda.h>
#include <math.h>
//#include "cublas.h"
//datatype to match FORTRAN complex type
typedef float real;
typedef struct{
int nx;
int ny;
int nz;
int sz;
int tz;
} states;
void set_SPB(real **,int,states **,states **,int **);
//void set_SPB();
int find_minimum(int a[], int n,int start);
const real hc =197.32697,pi=3.1415927;
int main(){
int nmax = 2, A = 28;
real *etemp, *fock;
int *Ndex,*lookup,*lookup_a;
states *channel,*SPB;
//!generates the single particle basis to be used
set_SPB(&etemp,nmax,&SPB,&channel,&Ndex);
free(etemp);
free(Ndex);
free(SPB);
return 0;
}
void set_SPB(real **etemp,int nmax,states **SPB,states **channel,int **Ndex){
int tot_orbs = (2*nmax+1)*(2*nmax+1)*(2*nmax+1)*4;
int D = tot_orbs/4;
int Nalpha = (2*nmax+1)*(2*nmax+1)*(2*nmax+1)*9;
real E;
*etemp = (real*)malloc(D);
*Ndex = (int*)malloc(D*3);
*SPB = (states*)malloc(tot_orbs);
printf("orbits without spin degeneracy %d \n",D);
printf("size of etemp %ld \n",sizeof(*etemp)/sizeof(*etemp[0]));
return;
int i = 0;
for(int nx =-nmax;nx<=nmax;nx++){
for(int ny =-nmax;ny<=nmax;ny++){
for(int nz =-nmax;nz<=nmax;nz++){
E = 0.5*4.0*pi*pi*(nx*nx+ny*ny+nz*nz);
//printf("%d\n",i);
*etemp[i] = E;
*Ndex[0*D+i] =nx;
*Ndex[1*D+i] = ny;
*Ndex[2*D+i] = nz;
i+=1;
}
}
}
return;
}
Also I am not sure exactly if my assignments of the arrays are correct.
Specifically the print to find the number of elements of that have been allocated always gives 2, when it should be D = 125.
I cannot believe that float and int take only 1 byte in your environment.
Multiply the size to be allocated by size of their elements.
*etemp = malloc(sizeof(**etemp) * D);
*Ndex = malloc(sizeof(**Ndex) * D*3);
*SPB = malloc(sizeof(**SPB) * tot_orbs); /* not sure because this is not used */
Note that they say you shouldn't cast the result of malloc() in C.
Also note that [] operator has higher precedence than * operator, so you have to use parentheses to use the arrays.
(*etemp)[i] = E;
(*Ndex)[0*D+i] =nx;
(*Ndex)[1*D+i] = ny;
(*Ndex)[2*D+i] = nz;
What I am trying to do is use a structure to create and display a 2D array of characters in the function 'function1( )'. This array will be sent back to the main( ) so I can use it further in my program. However my program is plagued with problems. I am having trouble with pointers. I assume my problem is somewhere with either my pointers or my variables. I've tried several combinations with no effort. As a beginner, it probably is some odd combination that is not coming to my mind.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 13
#define COL 16
typedef struct letter_array {
char** letters;
struct letter_array *ltr_ptr;
} larray;
void function1 (larray ** letter1[*][16]);
int function2 (larray letter2[][16]);
int function3 (larray letter3[][16]);
void function4 (int hor_ans, int ver_ans);
int main (void)
{
larray letter_list;
int vert, hori, **lptr;
lptr = malloc(ROW*sizeof(int*));
for(vert = 0; vert<ROW; vert++)
{
lptr [vert] = malloc(COL*sizeof(int));
}
printf("\n \t\t\t *** Hello! ***");
printf("\n This program will create a random selection of 180 upper-case"
" characters. \n\n");
function1(&letter_list); //Problem #1
printf("\n\nThank you for using my random character array program. \n"
"\t\t Have a good day! \n");
return ( 0 ) ;
}
void function1 (larray **letter1 [][16])
{
int i, z, funptr;
srandom((unsigned)time(NULL));
for(i=0; i<12; i++)
{
letter1 [i] <- (int*) funptr; // Problem #2-3
for(z=0; z<15; z++)
{
letter1[i][z] = random( )%26+'A'; // Problem #4
printf("%c ", letter1[i][z]);
}
printf("\n");
}
return ;
}
The errors are below and commented.
warning:passing argument 1 of 'function1' from incompatible pointer type
warning: cast to pointer from integer of different size
error: wrong type argument to unary minus
warning: assignment makes pointer from integer without a cast
I hope this helps.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 13
#define COL 16
typedef struct letter_array {
char** letters;
struct letter_array *ltr_ptr;
} larray;
void function1 (larray * letter1); // here you just need a pointer to the structure
int function2 (larray letter2[][16]);
int function3 (larray letter3[][16]);
void function4 (int hor_ans, int ver_ans);
int main (void)
{
larray letter_list;
int vert, hori;
letter_list.letters = malloc(ROW*sizeof(int*)); // allocate memory to the char pointer in the structure
for(vert = 0; vert<ROW; vert++)
{
letter_list.letters[vert] = malloc(COL*sizeof(int)); // allocate the second 2D
}
printf("\n \t\t\t *** Hello! ***");
printf("\n This program will create a random selection of 180 upper-case"
" characters. \n\n");
function1(&letter_list); //Problem #1 pass a pointer to the structure
printf("\n\nThank you for using my random character array program. \n"
"\t\t Have a good day! \n");
return ( 0 ) ;
}
void function1 (larray *letter1) // just needs a pointer to the structure
{
int i, z;
srandom((unsigned)time(NULL));
for(i=0; i<ROW; i++) // used ROW
{
//letter1->letters[i] <- (int*) funptr; // Problem #2-3 this line not needed as near as i can tell
for(z=0; z<COL; z++) // used COL
{
letter1->letters[i][z] = random( )%26+'A'; // Problem #4 dereference pointer to member char **
printf("%c ", letter1->letters[i][z]);
}
printf("\n");
}
return ;
}
I want to use this code in a more complex problem, but I didn't get it to work. Why isn't my matrix getting printed?
#include <stdio.h>
#include <stdlib.h>
void print_mat(int **a, int n)
{
printf("\n");
int k,t;
for (k=1;k<=n;k++)
{
for (t=1;t<=n;t++)
printf("%d ", a[k][t]);
printf("\n");
}
}
int main()
{
int i,j,n,**a;
printf("Chess board size=");
scanf("%d", &n);
a=(int **)malloc(n*sizeof(int));
for (i=1;i<=n;i++)
a[i]=(int*)malloc(n*sizeof(int));
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
a[i][j]=-1;
print_mat(a,n);
return 0;
}
You should first malloc for size of int * not int , change
a = ( int ** )malloc( n * sizeof( int ) );
to
a = malloc( n * sizeof( int* ) ); //also no need to cast.
Also, as #Russell Borogove suggested, change loop as for( i = 0; i < n; i++ ) instead of from 1 to n.
You will want to get in the habit of using zero-based indexes with C arrays, and display them as if they were 1-based only when presenting things to users.
Change your for (i=1;i<=n;i++) loops to for (i=0;i<n;i++). Likewise with j, k, and t.
As currently written, a[n] isn't an allocated pointer, and a[0][n] isn't within the a[0] buffer allocation. The result (gcc 4.2.1 on OSX 10.7.5) is a program crash.
The line
a=(int **)malloc(n*sizeof(int));
should read
a=malloc(n*sizeof(int *));
a=(int **)malloc(n*sizeof(int));
change to a= mallo(n*sizeof(int*))
On some systems int and int* (pointers) can have same size but here may be this is creating the problem.
Also
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
a[i][j]=-1;
change it to
for (i=0;i<n;i++)
for (j=0;j<n;j++)
a[i][j]=-1;