View Full Version : C problemi funzione puntatore per vettore
RINGRAZIO SUBITO PER L'ATTENZIONE!
L'esercizio chiedeva di usare una funzione:
int * negativi(int a[],int n,int *c);
per il ritorno di un vettore di negativi presi da un altro primo vettore.
trovo dei problemi nel ritorno del vettore di negativi..funziona tutto ma al momento di stampa del vett. mi da solo zeri.
nell'esempio dell'esercizio veniva usata una funzione MAXALLOCAZIONE su risultato..può essere questo il problema?
ecco il codice completo:
#include <stdio.h>
int * negativi(int a[],int n,int* c);
int carica(int a[]);
#define MAX 20
int main(){
int a[MAX+1];
int b[MAX+1]={0};
int* c;
int i,n,j;
c=&j;
n=carica(a);
int* p1;
p1=&b[0];
for(i=0;i<n;i++)
printf("- %d ",*(a+i));
printf("\nCERCO I NEGATIVI\n");
p1=negativi(a,n,c);
for(i=0;i<j;i++)
printf("- %d ",*(b+i)); //stampa vettore di negativi
}
//-----------------
int carica(int a[]){
int i,val;
int n=0;
for(i=0;i<MAX;i++){
scanf("%d",&val);
if(val!=-1){
a[i]=val;
n++;
}
else
break;
}
return n;
}
int * negativi(int a[],int n,int* c){
int* risultato;
int i;
int j=0;
for(i=0;i<n;i++){
if(a[i]<0){
risultato[j]=a[i]; //riempimento vettore di negativi
j++;
}
}
*c=j;
return risultato;
}
Sono un pelo arrugginito col c++ ma.. quel carica.. cosa è che carica?
Non vedo puntatori quindi sono tutte variabili locali e quando poi tu le richiami in cerca va a cercare roba in un array non inizializzato.
A me sotto linux infatti va in core dump.
Prova a debuggare mettendo un break sulla funzione e vedere cosa passa come valori.
risultato:
1
-3
4
5
6
1,-3,4,5,6,
CERCO I NEGATIVI
-3,
nota: #define MAX 5 al posto di 20
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
#include <stdio.h>
#include <conio.h>
int * negativi(int a[],int n,int* c);
int carica(int a[]);
#define MAX 5
int main()
{
int a[MAX+1];
int b[MAX+1]={0};
int *c;
int i,n,j;
c = &j;
n = carica(a);
int* p1;
p1=&b[0];
for(i=0;i<n;i++)
printf("%d,",*(a+i));
printf("\nCERCO I NEGATIVI\n");
p1 = negativi(a,n,c);
for(i=0;i<j;i++)
printf("%d,",*(p1+i)); //stampa vettore di negativi
// perchè b e non p1??????
getch(); // mia aggiunta
}
//-----------------
int carica(int a[])
{
int i,val;
int n=0;
for(i=0;i<MAX;i++)
{
scanf("%d",&val);
if(val!=-1)
{
a[i]=val;
n++;
}
else
break;
}
return n;
}
int * negativi(int a[],int n,int *c)
{
int *risultato;
risultato = (int *)malloc(5); // mia aggiunta
int i;
int j=0;
for(i=0;i<n;i++)
{
if(a[i]<0)
{
risultato[j] = a[i]; //riempimento vettore di negativi
j++;
}
}
*c = j;
return risultato;
}
grazie ho risolto il problema!
era questo pezzo:
for(i=0;i<j;i++)
printf("- %d ",*(p1+i)); //con *(b+i) non mi funziona..come mai?
//gli elementi non dovrebbero trovarsi in b[ ]
inoltre volevo sapere di più su:
#include <vcl.h> //questo
#pragma hdrstop //questo
//---------------------------------------------------------------------------
#pragma argsused //questo
#include <stdio.h>
#include <conio.h> //questo è solo per C++?
Poiché mai trattati nel mio corso (C senza accenni di C++)
Anche sinteticamente senza farvi perdere troppo tempo! ;)
Grazie ancora per l'aiuto e l'attenzione!
inoltre volevo sapere di più su:
#include <vcl.h> //questo
#pragma hdrstop //questo
//---------------------------------------------------------------------------
#pragma argsused //questo
#include <stdio.h>
#include <conio.h> //questo è solo per C++?
#include <vcl.h> <- Richiama le funzioni Visual Component Library, utili per interfacciarsi con windows
pragma hdrstop <- https://docs.microsoft.com/en-us/cpp/preprocessor/hdrstop?view=vs-2019
pragma argsused dice che la prossima funzione non dove preoccuparsi se il parametro non viene mai invocato
conio.h sono le funzioni per leggere quello che gli passi nel prompt essenzialmente
Al volo, mi riferisco al sorgente originale:
int * negativi(int a[], int n, int* c)
{
int* risultato;
int i;
int j=0;
for (i=0; i<n; i++) {
if (a[i] < 0) {
risultato[j]=a[i]; //riempimento vettore di negativi
j++;
}
}
*c=j;
return risultato;
}
Ho indendato un po' il codice per renderlo più leggibile, mi raccomando ragazzi fatelo sempre.
La prima cosa che si vede è che usi un puntatore non inizializzato, un errore abbastanza grave, se fossi mio studente ti avrei dato 0 :p.
Premessa: ti suggerisco di studiarti per bene la differenza tra array e puntatori (e si, c'è differenza e non poca al contrario di quello che molti pensano).
Un puntatore altro non è che un indirizzo ad un area di memoria. Nel tuo caso, il puntatore non è inizializzato o meglio possiamo considerare il suo contenuto praticamente RANDOM.
Nella migliore delle ipotesi il tuo programma ti dà dati sballati, nella peggiore crasha.
La domanda che devi farti è, dove metto questi valori?
Ci sono due possibilità, stack oppure heap. La memoria stack è già allocata ed è quella in cui sono appoggiate le variabili automatiche, che vengono create all'entrata di una funzione e "distrutte" al termine. Risultato, i e j sono variabili automatiche ad esempio, al termine della funzione la loro memoria non è più disponibile (le cose sono un po' diverse di così ma non voglio complicarti la vita).
Un array non può essere restituito da una funzione C. Questo significa che puoi restituire solo il suo indirizzo di base. L'indirizzo che restituisci al termine della funzione non può puntare ad un area dello stack della stessa funzione perché come detto non sarebbe più raggiungibile.
Quindi hai due strategie:
1) passi un puntatore ad un area pre-allocata, ad esempio così:
void negativi(int a[], int n, int* c, int* risultato);
E nella funzione invocante allochi l'area, ad esempio:
void funzione_invocante(void)
{
int a[3] = { -1, 0, 1 };
int ris[3] = { 0, };
int num_insert;
negativi(a, 3, &num_insert, ris);
}
Oppure,
2) usi la funzione di allocazione dinamica malloc(), come ti ha suggerito misterx.
Questa funzione prende in input il numero di bytes da allocare e restituisce un puntatore diverso da NULL se l'allocazione è andata a buon fine.
Nota che in questo caso l'allocazione avviene in un'area di memoria chiamata "heap" che non viene liberata in automatico.
Al termine del suo utilizzo va usata la funzione free() che prende in ingresso il puntatore restituito da malloc():
int* vettore = malloc(5 * sizeof(int)); /* alloco lo spazio per 5 interi */
if (vettore == NULL) {
fprintf(stderr, "Errore durante l'allocazione!!!\n");
...
/* exit() o return codice di errore */
}
negativi(..., vettore);
/* fai qualcosa con vettore */
free(vettore);
Nota il sizeof() nella malloc: questa funzione restituisce la dimensione in bytes del tipo o della variabile passata come argomento.
Siccome malloc() prende in ingresso la dimensione in bytes, devi considerare l'occupazione di memoria del tuo vettore.
Se sono interi significa che ciascun elemento occuperà sizeof(int) bytes quindi allocare lo spazio per 5 interi significa allocare 5*sizeof(int) bytes.
Mi sono dilungato ma spero sia stato chiaro :read:
Volutomitra
07-02-2020, 19:14
Ho indendato un po' il codice per renderlo più leggibile, mi raccomando ragazzi fatelo sempre.
Grazie! Quando leggo queste cose mi si apre il cuore! Grazie veramente! :D
Va bene anche il resto che hai scritto, ma questa te la dovevo quotare. E' tutto il giorno che sistemo il codice scritto da uno che non indenta manco se sennò muore :muro:
Grazie! Quando leggo queste cose mi si apre il cuore! Grazie veramente! :D
Va bene anche il resto che hai scritto, ma questa te la dovevo quotare. E' tutto il giorno che sistemo il codice scritto da uno che non indenta manco se sennò muore :muro:
Se usi Linux ti suggerisco di dare un'occhiata al programma indent :Prrr:
Mi sono dilungato ma spero sia stato chiaro :read:
Chiarissimo. Non posso che ringraziare.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.