I'm writing a program that calculates the greatest common denominator of two numbers, but i'm getting problem with malloc function and pointers. Actually it's clear how the stack and the heap segments work in the memory and why. But yet i'm not yet able to understand when declaring a pointer and using malloc is functional or not, is necessary or not, in a program. here is the code :
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
int *calcolaDivisori(int);
int main(int argc, char** argv) {
int foundCounter = 0;
int i,j,s1,s2;
int n1,n2;
int mcd = 1,mcm;
int *pn1,*pn2;
int d1[100],d2[100];
// INPUT dei due interi
printf("Inserisci il primo numero :");
scanf(" %d", &n1);
printf("\nInserisci il secondo numero :");
scanf(" %d", &n2);
// calcolo divisori del primo e del secondo numero e li assegno ai relativi array
pn1 = calcolaDivisori(n1);
if (!pn1) return 1;
pn2 = calcolaDivisori(n2);
if (!pn2) return 1;
for (i=0;i<n1;i++) {
d1[i] = pn1[i];
}
for (i=0;i<n2;i++) {
d2[i] = pn2[i];
}
free(pn1);
free(pn2);
// confronto i divisori e calcolo il MCD
s1 = sizeof(d1) / sizeof(int);
s2 = sizeof(d2) / sizeof(int);
for(i=0; i<s1; i++) {
for (j=foundCounter; j<s2;j++) {
if (d1[i] == d2[j]) {
mcd*= d1[1];
foundCounter = j+1;
break;
}
}
}
printf("\n\nIl minimo comune divisore e' : %d", mcd);
return 0;
}
int *calcolaDivisori(int num) {
int i;
int *a = malloc(num * sizeof(int));
if (!a) return NULL;
for (i=2;i<num;i++) {
if (num%i == 0) {
num/=i;
a[i-2]=i;
}
}
return a;
}
I get the error in the title when is run the command :
int *a = malloc(sizeof(int));
You need to cast:
int *a = (int*)malloc(num * sizeof(int));
Because there's no implicit conversion from void* to type * in C++.
Note that this cast is not required in C and could potentially be dangerous to do so in C.
Except for #include <iostream>, nothing in your code is C++. So remove it and compile it with a C compiler and you wouldn't need this cast.
Related
I want to make a program that returns the average of the numbers entered but i get this error:
incompatible types when assigning to type ‘float *’ from type ‘float’
#include <stdio.h>
#include <stdlib.h>
#define CANT ((int)99)
float* promedio (float *dataPtr, int dataCant)
{
float *p;
int a;
float total;
for ( a = dataCant; a >= 0; a--) {
total += *dataPtr;
*dataPtr +=1;
}
p = total / dataCant;
return (p);
}
int main (void)
{
float v[CANT],*q;
int i;
printf ("Ingrese numeros para calcular el promedio\r\n");
printf ("Use -1 para ver el promedio\r\n");
while ((i < CANT) || (v [i] != -1)) {
printf(" Ingrese un numero: \r \n");
scanf ("%f", &v[i]);
i++;
}
q = promedio (&v[0], i);
printf ("El promedio vale %f\r\n", *q);
free (v);
return (0);
}
Your approach of returning a pointer from promedio doesn't make much sens.
You probably want this:
void promedio (float *dataPtr, int dataCant, float *result)
{
int a;
float total;
for ( a = dataCant; a >= 0; a--) {
total += *dataPtr;
dataPtr +=1; // remove the *, you want to increment the pointer
} // not the thing it points to
*result = total / dataCant;
}
int main (void)
{
float v[CANT],*q;
int i;
printf ("Ingrese numeros para calcular el promedio\r\n");
printf ("Use -1 para ver el promedio\r\n");
while ((i < CANT) || (v [i] != -1)) {
printf(" Ingrese un numero: \r \n");
scanf ("%f", &v[i]);
i++;
}
float q;
promedio (&v[0], i); // you should write `v` innstead of the cumbersome `&v[0]`
printf ("El promedio vale %f\r\n", q); // q is a float, removge the *
// remove free (v), you can only free stuff allocated via malloc and friends
return (0);
}
Anyway, I have the strong impression you should read again the chapter dealing with pointers in your learning material.
It turns out you rather need this:
float promedio (float *dataPtr, int dataCant)
{
int a;
float total;
for ( a = dataCant; a >= 0; a--) {
total += *dataPtr;
dataPtr +=1; // remove the *, you want to increment the pointer
} // not the thing it points to
return = total / dataCant;
}
#Jabberwocky
Thank you for your answer, thanks it I managed to solve the exercise. This is the answer (works)
#include <stdio.h>
#include <stdlib.h>
#define CANT ((int)99)
float promedio (float *dataPtr, int dataCant)
{
int a;
float total;
for ( a = dataCant; a >= 0; a--) {
total += *dataPtr;
dataPtr +=1;
}
return (total / dataCant);
}
int main (void)
{
float v[CANT], q, a;
int i=0;
printf ("Ingrese numeros para calcular el promedio\r\n");
printf ("Use -1 para ver el promedio\r\n");
while ((i < CANT) && (a != -1)) {
printf(" Ingrese un numero: \r \n");
scanf ("%f", &a);
if (a != -1) {
v[i]=a;
i++;
}
}
q = promedio (&v[0], i);
printf ("El promedio vale %0.2f\r\n", q);
return (0);
}
this is my first question on StackOverflow ! :)
To be honest I'm about to destroy my whole setup.
My code is making me crazy.
My problem is, I am not able to fill a dynamic array with the return of a function.
My goal here is, for each array box, fill it with a random value of 'randomizer'. I am not able to take the return of randomizer in the array box.
Here is the code:
main.c:
#include "functions.h"
#include "functions.c"
/* TP 3 - ESIEE-IT Rémy JARDIN */
int main() {
int saisie, i;
printf("Creation du Tableau. \nNombre de caractere du tableau : ");
scanf("%d", &saisie);
ArrayCreate(saisie);
// Affichage
return 0;
}
functions.h:
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
#include <stdio.h>
#include <stdlib.h>
int ArrayCreate(int saisie);
int randomizer();
int insereAIndice();
#endif
functions.c:
#include <stdio.h>
#include <stdlib.h>
int ArrayCreate(int saisie) {
int i;
int *Tab = (int *)malloc(saisie * sizeof(int));
if (Tab == NULL) {
printf("Not enough Memory");
exit (1);
}
for (i = 0; i < saisie; i++) {
Tab[i] = (randomizer + 1);
}
printf("\n Resultats : ");
for (i = 0; i < saisie; i++) {
printf("%d - ", *(Tab + i));
}
return 0;
}
int randomizer() {
//int x = rand() % (100 + 1);
return 1;
}
And the error is:
functions.c: In function 'ArrayCreate':
functions.c:12:8: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
Tab[i] = (randomizer+1);
Instead of Tab[i] = (randomizer + 1); you should write:
Tab[i] = randomizer();
Note also these remarks:
the function prototypes in functions.h should have an argument of void:
int randomizer(void);
int insereAIndice(void);
file functions.c should include functions.h to ensure consistency between function declarations and definitions.
Writing *(Tab + i) is much less readable than Tab[i]. If you wish to obfuscate the code, use i[Tab] which is equivalent :)
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
#include "functions.h"
int ArrayCreate(int saisie) {
int i;
int *Tab = (int *)malloc(saisie * sizeof(int));
if (Tab == NULL) {
fprintf(stderr, "Not enough Memory\n");
exit(1);
}
for (i = 0; i < saisie; i++) {
Tab[i] = randomizer();
}
printf("\n Resultats : ");
for (i = 0; i < saisie; i++) {
printf(" %d", Tab[i]);
}
printf("\n");
return 0;
}
int randomizer(void) {
// return a random integer in the range 1..100
return 1 + rand() % 100;
}
I am trying to read from 2 files (f1.txt and f2.txt) using structures and print them out to the third file (f3.txt), but I seem to be getting some errors. Issues did not occur before I tried printing out the values to the file (fprintf command), and I cant seem to find a way to fix it..
This is for a homework assignment, but since I've been struggling to fix this issue for months now (yes, I'm pretty bad), I thought maybe anyone here knows how I can fix this.
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define MAX_NIME_PIKKUS 100
#define MAX_AINE_PIKKUS 100
#define MAX_KOOD 10
#define MAX_HINNE 5
#define DEBUG 0
int n;
int m;
struct Tudeng{
char Nimi[MAX_NIME_PIKKUS];
char Kood[MAX_KOOD];
};
struct Tudeng *pTudeng;
struct Aine{
char Nimetus[MAX_AINE_PIKKUS];
char aineKood[MAX_KOOD];
};
struct Aine *pAine;
struct Tud{
char Tudengikood[MAX_KOOD];
int Hinne[MAX_HINNE];
};
struct Tud *pTud;
char f1[] = "f1.txt";
char f2[] = "f2.txt";
char f3[] = "f3.txt";
FILE *fp1,*fp2,*fp3;
int sisendf1_kontroll();
int sisendf2_kontroll();
void tekita_failid();
void andmed_failidesse(char Tudeng1, char Tudeng2, char Aine1, char Aine2, char Tud1, int Tud2);
int main(void){
int a;
int b;
int c;
n = sisendf1_kontroll();
printf("Failist %s loeti %d tudengi andmed.\n", f1, n);
m = sisendf2_kontroll();
printf("Failist %s loeti %d aine andmed.\n", f2, m);
fp1 = fopen(f1,"r");
fp2 = fopen(f2, "r");
int i = 0;
a = sizeof(struct Tudeng);
b = sizeof(struct Aine);
c = sizeof(struct Tud);
pTudeng = malloc(a * n);
pAine = malloc(b * m);
pTud = malloc(c * m);
if(DEBUG)printf("Struktuuri Tudeng baidi aadress on %p, ühe kirje andmeteks eraldati mälu %d baiti, mälu eraldati massiivile kokku %d baiti \n", pTudeng, a, a * n);
if(DEBUG)printf("Struktuuri Aine baidi aadress on %p, ühe kirje andmeteks eraldati mälu %d baiti, mälu eraldati massiivile kokku %d baiti \n", pAine, b, b * m);
if(DEBUG)printf("Struktuuri Tud baidi aadress on %p, ühe kirje andmeteks eraldati mälu %d baiti, mälu eraldati massiivile kokku %d baiti \n", pTud, c, c * m);
int loopiks;
while(loopiks == 0){
while(!feof(fp1)){
fscanf(fp1,"%s",(pTudeng+i)->Nimi);
fscanf(fp1,"%s",(pTudeng+i)->Kood);
i++;
}
while(!feof(fp2)){
fscanf(fp2,"%s",(pAine+i)->Nimetus);
fscanf(fp2,"%s",(pAine+i)->aineKood);
fscanf(fp2,"%s",(pTud+i)->Tudengikood);
fscanf(fp2,"%d",(pTud+i)->Hinne);
i++;
}
loopiks = 1;
tekita_failid();
andmed_failidesse((pTudeng+i->Nimi), (pTudeng+i)->Kood, (pAine+i)->Nimetus, (pAine+i)->aineKood, (pTud+i)->Tudengikood, (pTud+i)->Hinne);
free(pTudeng);
free(pAine);
free(pTud);
}
//fprintf(fp3, "%s %s\n",(pTudeng+i)->Nimi,(pTudeng+i)->Kood);
fclose(fp1);
fclose(fp2);
return 0;
}
int sisendf1_kontroll(void){
char rida[122];
int n = 0, p;
fp1 = fopen(f1,"r");
if(fp1 == NULL){
printf("Sisendfaili %s avamine ebaonnestus!", f1);
exit(1);
}else{
while(!feof(fp1)){
fgets(rida, 122, fp1);
p = strlen(rida);
if (p > 1) n++;
}
}
fclose(fp1);
return n;
}
int sisendf2_kontroll(void){
char rida2[122];
int m = 0, o;
fp2 = fopen(f2,"r");
if(fp2==NULL){
printf("Sisendfaili %s avamine ebaonnestus!", f2);
exit(1);
}else{
while(!feof(fp2)){
fgets(rida2, 122, fp2);
o = strlen(rida2);
if (o > 1) m++;
}
}
fclose(fp2);
return m;
}
void tekita_failid(){
fp3 = fopen(f3, "w");
fclose(fp3);
return;
}
void andmed_failidesse(char Tudeng1, char Tudeng2, char Aine1, char Aine2, char Tud1, int Tud2){
fp3 = fopen(f3, "a");
int i;
int j;
while(i < n && j < m){
for(i = 0; i < n; i++){
fprintf(fp3, "%s %s ",(pTudeng+i)->Nimi,(pTudeng+i)->Kood);
}
for(j = 0; j < m; j++){
fprintf(fp3, "%s %s %s %d \n",(pAine+i)->Nimetus,(pAine+i)->aineKood, (pTud+i)->Tudengikood, (pTud+i)->Hinne);
}
}
return;
}
I expected the program to output the information from f1.txt and f2.txt to f3.txt, but currently compiler tells me that I cannot do that, since I'm using * int in last function, but it says that regular int is required.
Compiler is right:
andmed_failidesse expects an int as last parameter and you're passing Hinne which is an array of int, aka int*.
As Tud2 is not used anyway in your current code you can remove it from function signature or rework your function to use it.
Your compiler should also warn you that you have other unused parameters in your function.
It is obviously a work in progress: take a break, re-read your C courses and try to figure out what your function is supposed to do, and which parameters it needs.
I was trying to do this work for a class i have but for some reason i can't get the rand() to work, i've tested several diferent things to try and get it to work, but i just can't figure it out. I'm new to C so i might be doing something wrong here please help.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int main() {
srand( time(NULL) );
int num, rep, nu, ba, bas;
char B[20] = "";
char C[20] = "";
printf("Jogo: Converter Bases!\n");
printf("\n Quantas perguntas desejas responder? (1-6)");
scanf("%d", &num);
while (num <= 0 || num > 6) {
printf("\n Introduz um valor valido de 1 a 6: ");
scanf("%d", &num);
}
for (int p=0; p<num; p++) {
nu=rand()% 10;
bas=rand()% 3;
ba=rand()% 3;
printf("\nnu = %i bas = %i ba = %i", &nu, &bas, &ba);
while (ba = bas) {
ba = rand()% 3;
}
if (bas = 0) {
char B[20] = "Octal";
} else if (bas =1) {
char B[20] = "Decimal";
} else {
char B[20] = "Hexadecimal";
}
if (ba = 0) {
char C[20] = "Octal";
} else if (ba =1) {
char C[20] = "Decimal";
} else {
char C[20] = "Hexadecimal";
}
printf("Converte %i de base %c para base %c\n", &nu, &B, &C);
scanf("%d", &rep);
}
return 0;
}
`
It's because you're writing:
printf("%d", &x);
When you should be writing
printf("%d", x);
In the first case you're printing the memory address of the variable; in the second - the contents of the variable.
The & is required for scanf, because it needs to know the memory address where to put the results, but printf only needs the value.
i'm learnig how to code in C.
i have to create a record for a person, with an birthday and a ID number
the code is composed of 3 files
the fist is a header
// definição do tipo
typedef int vetor[10];
typedef struct
{
char nome[50];
vetor nasceu;
vetor cpf;
} dados ;
void cadastro (dados*, char[50], vetor, vetor);
then there is the definitions of the header
#include <stdio.h>
#include <string.h>
#include "cadastro.h"
void cadastro (dados *usuario, char name[50], vetor ddn, vetor cpf)
{
int i;
strcpy(usuario->nome,name);
for (i = 0; i < 50; i++)
{
usuario->nasceu[i] = ddn[i];
}
for (i = 0; i < 10; i++)
{
usuario->cpf[i] = cpf[i];
}
}
and the last file uses the header to generate the record
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cadastro.h"
int preenche_cadastro (char a[],vetor b,vetor c)
{
int i;
printf ("inserir nome: ");
gets (a);
printf("inserir data de nascimento (campos separados por espaco): ");
for (i = 0; i < 3; i++)
{
scanf("%d",&b[i]);
}
printf ("inserir CPF (campos separados por espaco): ");
for (i = 0; i < 4; i++)
{
scanf("%d",&c[i]);
}
return (0);
}
int imprime_cadastro (dados usuario)
{
printf("\nnome: %s",usuario.nome);
printf("\ndata de nascimento: %d / %d / %d\n", usuario.nasceu[0],usuario.nasceu[1],usuario.nasceu[2]);
printf("CPF: %d . %d . %d - %d\n", usuario.cpf[0],usuario.cpf[1],usuario.cpf[2],usuario.cpf[3]);
return(0);
}
int main(void)
{
dados new_entry;
char name[50];
vetor born, cpf;
int i;
preenche_cadastro (name,born,cpf);
cadastro(&new_entry, name, born, cpf);
imprime_cadastro(new_entry);
return (0);
}
i don't really know how to debug, but as far as i could tell, the `Segmentation fault' occurs only at the line
return (0);
i'm going mad here, can anybody help me?
sorry for my english, it's not mother language
You invoked undefined behavior by accessing out-of-range of array in the line
usuario->nasceu[i] = ddn[i];
in function cadastro, and then the program happened to crash there.
Do not invoke undefined behavior. Instead of using magic number 10, you should define the number of elements in the array and use it.
Also note that using values of uninitialized variables having automatic storage duration, which are indeterminate, also invokes undefined behavior.
corrected header:
// definição do tipo
#define VETOR_NUM 10
typedef int vetor[VETOR_NUM];
typedef struct
{
char nome[50];
vetor nasceu;
vetor cpf;
} dados ;
void cadastro (dados*, char[50], vetor, vetor);
corrected implementation of cadastro:
#include <stdio.h>
#include <string.h>
#include "cadastro.h"
void cadastro (dados *usuario, char name[50], vetor ddn, vetor cpf)
{
int i;
strcpy(usuario->nome,name);
for (i = 0; i < VETOR_NUM; i++)
{
usuario->nasceu[i] = ddn[i];
}
for (i = 0; i < VETOR_NUM; i++)
{
usuario->cpf[i] = cpf[i];
}
}
corrected main() function:
int main(void)
{
dados new_entry;
char name[50];
vetor born = {0}, cpf = {0}; /* initialize arrays */
/* i is removed because it wasn't used */
preenche_cadastro (name,born,cpf);
cadastro(&new_entry, name, born, cpf);
imprime_cadastro(new_entry);
return (0);
}
One more note: You shouldn't use gets(), which has unavoidable risk of buffer overrun.
Your first loop should only copy 10 items rather than 50.
for (i = 0; i < 10; i++)
{
usuario->nasceu[i] = ddn[i];
}
This loop in your cadastro function:
for (i = 0; i < 50; i++)
{
usuario->nasceu[i] = ddn[i];
}
Seems to not be in line with the size of the nasceu arrary:
typedef int vetor[10];
typedef struct
{
char nome[50];
vetor nasceu;
vetor cpf;
} dados ;
Have you tried changing to:
for (i = 0; i < 10; i++)
{
usuario->nasceu[i] = ddn[i];
}
?